├── log └── .keep ├── mysql └── .keep ├── app ├── mailers │ ├── .keep │ ├── application_mailer.rb │ └── project_mailer.rb ├── models │ ├── .keep │ ├── concerns │ │ └── .keep │ ├── stage.rb │ ├── app_information.rb │ ├── project_update_history.rb │ ├── skill.rb │ ├── project_update.rb │ ├── user.rb │ └── project.rb ├── assets │ ├── images │ │ ├── .keep │ │ ├── matsu │ │ │ ├── .keep │ │ │ ├── nav.gif │ │ │ ├── logo.png │ │ │ ├── member.png │ │ │ ├── num_back.png │ │ │ ├── header_item1.png │ │ │ ├── header_item2.png │ │ │ ├── header_item3.png │ │ │ ├── menu_item01.png │ │ │ └── sample_thum.jpg │ │ ├── logo_cfk.png │ │ ├── logotype.png │ │ ├── ha4go_icon.png │ │ ├── img_kanazawa.jpg │ │ └── Feed-icon.svg │ ├── stylesheets │ │ ├── matsu │ │ │ ├── _font.scss │ │ │ ├── _color.scss │ │ │ ├── jquery.mobile.menu.css │ │ │ └── reset.scss │ │ ├── top.scss │ │ ├── sessions.scss │ │ ├── project_updates.scss │ │ ├── projects.scss │ │ ├── bootstrap_override.scss │ │ ├── users.scss │ │ ├── application.scss │ │ ├── dashboard.scss │ │ └── common.scss │ └── javascripts │ │ ├── top.coffee │ │ ├── users.coffee │ │ ├── dashboard.coffee │ │ ├── sessions.coffee │ │ ├── project_updates.coffee │ │ ├── facebook.js.coffee.erb │ │ ├── projects.coffee │ │ ├── application.js │ │ ├── matsu │ │ ├── html5shiv.js │ │ ├── jquery.sidr.min.js │ │ └── jquery.mobile-menu.js │ │ └── skill_quick_add.js ├── controllers │ ├── concerns │ │ ├── .keep │ │ └── sns_publisher.rb │ ├── dashboard_controller.rb │ ├── top_controller.rb │ ├── sessions_controller.rb │ ├── application_controller.rb │ ├── users_controller.rb │ ├── project_updates_controller.rb │ └── projects_controller.rb ├── views │ ├── layouts │ │ ├── mailer.text.erb │ │ └── mailer.html.erb │ ├── users │ │ ├── new.html.erb │ │ ├── edit.html.erb │ │ ├── index.html.erb │ │ ├── _form.html.erb │ │ └── show.html.erb │ ├── project_updates │ │ ├── edit.html.erb │ │ ├── new.html.erb │ │ ├── show.html.erb │ │ ├── _form.html.erb │ │ └── index.html.erb │ ├── top │ │ ├── index.html.erb │ │ ├── help.html.erb │ │ └── feed.rss.builder │ ├── shared │ │ ├── _twitter.html │ │ ├── _facebook.html │ │ ├── _ogp_project.html.erb │ │ ├── _ogp_common.html.erb │ │ └── _project.html.erb │ ├── project_mailer │ │ ├── sendmail_confirm.html.erb │ │ ├── tell_skill_match.html.erb │ │ ├── tell_create.html.erb │ │ └── tell_update.html.erb │ └── projects │ │ ├── edit.html.erb │ │ ├── index.html.erb │ │ ├── new.html.erb │ │ ├── show.rss.builder │ │ └── _form.html.erb ├── helpers │ ├── top_helper.rb │ ├── dashboard_helper.rb │ ├── projects_helper.rb │ ├── sessions_helper.rb │ ├── project_updates_helper.rb │ ├── users_helper.rb │ ├── sns_helper.rb │ ├── seo_helper.rb │ └── application_helper.rb ├── field_types │ └── array_type.rb ├── jobs │ └── post_to_sns_job.rb └── uploaders │ ├── image_uploader.rb │ └── comment_image_uploader.rb ├── lib ├── assets │ └── .keep └── tasks │ ├── .keep │ └── unlock_yml.rake ├── public ├── favicon.ico ├── uploads │ └── .keep ├── robots.txt ├── 500.html ├── 422.html └── 404.html ├── test ├── helpers │ └── .keep ├── mailers │ ├── .keep │ ├── project_mailer_test.rb │ └── previews │ │ └── project_mailer_preview.rb ├── models │ ├── .keep │ ├── skill_test.rb │ ├── stage_test.rb │ ├── user_test.rb │ ├── project_test.rb │ ├── app_information_test.rb │ ├── project_update_test.rb │ └── project_update_history_test.rb ├── controllers │ ├── .keep │ ├── dashboard_controller_test.rb │ ├── top_controller_test.rb │ ├── sessions_controller_test.rb │ ├── users_controller_test.rb │ ├── project_updates_controller_test.rb │ └── projects_controller_test.rb ├── fixtures │ ├── .keep │ ├── skills.yml │ ├── stages.yml │ ├── project_update_histories.yml │ ├── app_informations.yml │ ├── project_updates.yml │ ├── users.yml │ └── projects.yml ├── integration │ └── .keep ├── jobs │ └── post_to_sns_job_test.rb └── test_helper.rb ├── vendor └── assets │ ├── javascripts │ └── .keep │ └── stylesheets │ └── .keep ├── misc └── docker │ └── heroku-deploy │ ├── .gitignore │ └── Dockerfile ├── erd.pdf ├── bin ├── rake ├── bundle ├── rails ├── delayed_job ├── spring ├── update └── setup ├── Procfile ├── config ├── database.travis.yml ├── spring.rb ├── boot.rb ├── locales │ ├── views │ │ ├── project_updates │ │ │ └── ja.yml │ │ ├── top │ │ │ └── ja.yml │ │ ├── users │ │ │ └── ja.yml │ │ ├── project_mailer │ │ │ └── ja.yml │ │ ├── dashboard │ │ │ └── ja.yml │ │ ├── projects │ │ │ └── ja.yml │ │ └── ja.yml │ ├── ja.yml │ └── defaults │ │ ├── ja.yml │ │ └── en.yml ├── environment.rb ├── cable.yml ├── initializers │ ├── session_store.rb │ ├── mime_types.rb │ ├── application_controller_renderer.rb │ ├── filter_parameter_logging.rb │ ├── cookies_serializer.rb │ ├── kaminari_config.rb │ ├── backtrace_silencers.rb │ ├── omniauth.rb │ ├── wrap_parameters.rb │ ├── assets.rb │ ├── inflections.rb │ ├── carrierwave.rb │ └── new_framework_defaults.rb ├── database.yml ├── application.rb ├── secrets.yml ├── environments │ ├── test.rb │ ├── development.rb │ └── production.rb ├── puma.rb └── routes.rb ├── config.ru ├── db ├── migrate │ ├── 20150607001212_delete_index_user.rb │ ├── 20150606234247_drop_table_user_session.rb │ ├── 20150607035210_add_column_user.rb │ ├── 20170205014850_add_images_to_project.rb │ ├── 20160605184821_change_column_to_user.rb │ ├── 20161106085544_add_receive_all_to_user.rb │ ├── 20150426132854_add_index_email_to_users.rb │ ├── 20150429131447_add_index_name_to_skills.rb │ ├── 20160605183055_change_column2_to_project.rb │ ├── 20150426045247_remove_delete_flag_from_users.rb │ ├── 20150505071406_add_column_to_project_update.rb │ ├── 20161008063758_add_column_to_project_update2.rb │ ├── 20170205093033_add_image_to_project_update.rb │ ├── 20150426045307_remove_delete_flag_from_projects.rb │ ├── 20150429142635_rename_users_skills_to_skills_users.rb │ ├── 20161002065824_add_project_to_projects.rb │ ├── 20160605184658_change_column_to_project_update.rb │ ├── 20161203220548_add_last_commented_at_to_project.rb │ ├── 20150606234005_remove_column_user.rb │ ├── 20150614110547_change_column_to_project.rb │ ├── 20150426045313_remove_delete_flag_from_project_updates.rb │ ├── 20150607104348_add_index_user_id_to_project_users.rb │ ├── 20150429124203_create_skills.rb │ ├── 20150614102950_create_stages.rb │ ├── 20150429130453_create_users_skills.rb │ ├── 20150429143753_create_projects_users.rb │ ├── 20150505025435_create_projects_skills.rb │ ├── 20161106071526_create_app_informations.rb │ ├── 20150606131655_add_column_to_users.rb │ ├── 20160905094440_change_column_to_project2.rb │ ├── 20150426043346_create_project_updates.rb │ ├── 20150426023450_create_users.rb │ ├── 20161008044105_create_project_update_histories.rb │ ├── 20150426023934_create_projects.rb │ └── 20170507011046_create_delayed_jobs.rb ├── seeds │ ├── projects.yml.sample │ ├── development.rb │ └── users.yml.sample ├── seeds.rb └── schema.rb ├── Dockerfile.db ├── init.sql ├── .dockerignore ├── Dockerfile.dev ├── Rakefile ├── Dockerfile.front ├── .travis.yml ├── docker-compose.yml ├── .rubocop_todo.yml ├── .gitignore ├── .env.sample ├── .rubocop.yml ├── Dockerfile.base ├── app.json ├── Rakefile.deploy └── Gemfile /log/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /mysql/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/mailers/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/models/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /lib/assets/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /lib/tasks/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/helpers/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/mailers/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/models/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/assets/images/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/uploads/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/controllers/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/fixtures/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/integration/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/models/concerns/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/assets/images/matsu/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/controllers/concerns/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /vendor/assets/javascripts/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /vendor/assets/stylesheets/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/views/layouts/mailer.text.erb: -------------------------------------------------------------------------------- 1 | <%= yield %> 2 | -------------------------------------------------------------------------------- /misc/docker/heroku-deploy/.gitignore: -------------------------------------------------------------------------------- 1 | heroku_login 2 | -------------------------------------------------------------------------------- /app/helpers/top_helper.rb: -------------------------------------------------------------------------------- 1 | module TopHelper 2 | end 3 | -------------------------------------------------------------------------------- /app/helpers/dashboard_helper.rb: -------------------------------------------------------------------------------- 1 | module DashboardHelper 2 | end 3 | -------------------------------------------------------------------------------- /app/helpers/projects_helper.rb: -------------------------------------------------------------------------------- 1 | module ProjectsHelper 2 | end 3 | -------------------------------------------------------------------------------- /app/helpers/sessions_helper.rb: -------------------------------------------------------------------------------- 1 | module SessionsHelper 2 | end 3 | -------------------------------------------------------------------------------- /app/models/stage.rb: -------------------------------------------------------------------------------- 1 | class Stage < ActiveRecord::Base 2 | end 3 | -------------------------------------------------------------------------------- /app/helpers/project_updates_helper.rb: -------------------------------------------------------------------------------- 1 | module ProjectUpdatesHelper 2 | end 3 | -------------------------------------------------------------------------------- /erd.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeforkanazawa-org/ha4go/HEAD/erd.pdf -------------------------------------------------------------------------------- /app/models/app_information.rb: -------------------------------------------------------------------------------- 1 | class AppInformation < ActiveRecord::Base 2 | end 3 | -------------------------------------------------------------------------------- /app/views/layouts/mailer.html.erb: -------------------------------------------------------------------------------- 1 | 2 | 3 | <%= yield %> 4 | 5 | 6 | -------------------------------------------------------------------------------- /bin/rake: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require_relative '../config/boot' 3 | require 'rake' 4 | Rake.application.run 5 | -------------------------------------------------------------------------------- /app/assets/images/logo_cfk.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeforkanazawa-org/ha4go/HEAD/app/assets/images/logo_cfk.png -------------------------------------------------------------------------------- /app/assets/images/logotype.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeforkanazawa-org/ha4go/HEAD/app/assets/images/logotype.png -------------------------------------------------------------------------------- /app/assets/images/matsu/nav.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeforkanazawa-org/ha4go/HEAD/app/assets/images/matsu/nav.gif -------------------------------------------------------------------------------- /app/views/users/new.html.erb: -------------------------------------------------------------------------------- 1 |

New User

2 | 3 | <%= render 'form' %> 4 | 5 | <%= link_to 'Back', users_path %> 6 | -------------------------------------------------------------------------------- /Procfile: -------------------------------------------------------------------------------- 1 | release: bundle exec rails db:migrate 2 | web: bundle exec rails server -p $PORT 3 | worker: bundle exec rails jobs:work -------------------------------------------------------------------------------- /app/assets/images/ha4go_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeforkanazawa-org/ha4go/HEAD/app/assets/images/ha4go_icon.png -------------------------------------------------------------------------------- /app/assets/images/matsu/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeforkanazawa-org/ha4go/HEAD/app/assets/images/matsu/logo.png -------------------------------------------------------------------------------- /app/assets/images/img_kanazawa.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeforkanazawa-org/ha4go/HEAD/app/assets/images/img_kanazawa.jpg -------------------------------------------------------------------------------- /app/assets/images/matsu/member.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeforkanazawa-org/ha4go/HEAD/app/assets/images/matsu/member.png -------------------------------------------------------------------------------- /app/assets/images/matsu/num_back.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeforkanazawa-org/ha4go/HEAD/app/assets/images/matsu/num_back.png -------------------------------------------------------------------------------- /config/database.travis.yml: -------------------------------------------------------------------------------- 1 | test: 2 | adapter: mysql2 3 | database: myapp_test 4 | username: travis 5 | encoding: utf8 6 | -------------------------------------------------------------------------------- /app/assets/images/matsu/header_item1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeforkanazawa-org/ha4go/HEAD/app/assets/images/matsu/header_item1.png -------------------------------------------------------------------------------- /app/assets/images/matsu/header_item2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeforkanazawa-org/ha4go/HEAD/app/assets/images/matsu/header_item2.png -------------------------------------------------------------------------------- /app/assets/images/matsu/header_item3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeforkanazawa-org/ha4go/HEAD/app/assets/images/matsu/header_item3.png -------------------------------------------------------------------------------- /app/assets/images/matsu/menu_item01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeforkanazawa-org/ha4go/HEAD/app/assets/images/matsu/menu_item01.png -------------------------------------------------------------------------------- /app/assets/images/matsu/sample_thum.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeforkanazawa-org/ha4go/HEAD/app/assets/images/matsu/sample_thum.jpg -------------------------------------------------------------------------------- /app/helpers/users_helper.rb: -------------------------------------------------------------------------------- 1 | module UsersHelper 2 | def name_and_link(user) 3 | link_to(user.name, user_path(id: user.id)) 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /app/mailers/application_mailer.rb: -------------------------------------------------------------------------------- 1 | class ApplicationMailer < ActionMailer::Base 2 | default from: "from@example.com" 3 | layout 'mailer' 4 | end 5 | -------------------------------------------------------------------------------- /app/models/project_update_history.rb: -------------------------------------------------------------------------------- 1 | class ProjectUpdateHistory < ActiveRecord::Base 2 | belongs_to :project_update 3 | belongs_to :user 4 | end 5 | -------------------------------------------------------------------------------- /bin/bundle: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__) 3 | load Gem.bin_path('bundler', 'bundle') 4 | -------------------------------------------------------------------------------- /config/spring.rb: -------------------------------------------------------------------------------- 1 | %w( 2 | .ruby-version 3 | .rbenv-vars 4 | tmp/restart.txt 5 | tmp/caching-dev.txt 6 | ).each { |path| Spring.watch(path) } 7 | -------------------------------------------------------------------------------- /config/boot.rb: -------------------------------------------------------------------------------- 1 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __dir__) 2 | 3 | require 'bundler/setup' # Set up gems listed in the Gemfile. 4 | -------------------------------------------------------------------------------- /config/locales/views/project_updates/ja.yml: -------------------------------------------------------------------------------- 1 | ja: 2 | project_updates: 3 | new: 4 | add_comment: フォローを書き込む 5 | form: 6 | do_comment: 書き込む 7 | -------------------------------------------------------------------------------- /bin/rails: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | APP_PATH = File.expand_path('../config/application', __dir__) 3 | require_relative '../config/boot' 4 | require 'rails/commands' 5 | -------------------------------------------------------------------------------- /config/locales/views/top/ja.yml: -------------------------------------------------------------------------------- 1 | ja: 2 | top: 3 | index: 4 | overview: '課題を深く知る市民とシビックテックの情報交換サイト、はじめました。' 5 | register_facebook: 'Facebookで登録' 6 | -------------------------------------------------------------------------------- /config/environment.rb: -------------------------------------------------------------------------------- 1 | # Load the Rails application. 2 | require_relative 'application' 3 | 4 | # Initialize the Rails application. 5 | Rails.application.initialize! 6 | -------------------------------------------------------------------------------- /test/models/skill_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class SkillTest < ActiveSupport::TestCase 4 | # test "the truth" do 5 | # assert true 6 | # end 7 | end 8 | -------------------------------------------------------------------------------- /test/models/stage_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class StageTest < ActiveSupport::TestCase 4 | # test "the truth" do 5 | # assert true 6 | # end 7 | end 8 | -------------------------------------------------------------------------------- /test/models/user_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class UserTest < ActiveSupport::TestCase 4 | # test "the truth" do 5 | # assert true 6 | # end 7 | end 8 | -------------------------------------------------------------------------------- /config.ru: -------------------------------------------------------------------------------- 1 | # This file is used by Rack-based servers to start the application. 2 | 3 | require ::File.expand_path('../config/environment', __FILE__) 4 | run Rails.application 5 | -------------------------------------------------------------------------------- /config/cable.yml: -------------------------------------------------------------------------------- 1 | development: 2 | adapter: async 3 | 4 | test: 5 | adapter: async 6 | 7 | production: 8 | adapter: redis 9 | url: redis://localhost:6379/1 10 | -------------------------------------------------------------------------------- /db/migrate/20150607001212_delete_index_user.rb: -------------------------------------------------------------------------------- 1 | class DeleteIndexUser < ActiveRecord::Migration[4.2] 2 | def change 3 | remove_index :users, :email 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /test/models/project_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class ProjectTest < ActiveSupport::TestCase 4 | # test "the truth" do 5 | # assert true 6 | # end 7 | end 8 | -------------------------------------------------------------------------------- /db/migrate/20150606234247_drop_table_user_session.rb: -------------------------------------------------------------------------------- 1 | class DropTableUserSession < ActiveRecord::Migration[4.2] 2 | def down 3 | drop_table :user_sessions 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /db/migrate/20150607035210_add_column_user.rb: -------------------------------------------------------------------------------- 1 | class AddColumnUser < ActiveRecord::Migration[4.2] 2 | def change 3 | add_column :users, :image, :string 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /test/jobs/post_to_sns_job_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class PostToSnsJobTest < ActiveJob::TestCase 4 | # test "the truth" do 5 | # assert true 6 | # end 7 | end 8 | -------------------------------------------------------------------------------- /config/initializers/session_store.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | Rails.application.config.session_store :cookie_store, key: '_ha4go_session' 4 | -------------------------------------------------------------------------------- /app/assets/stylesheets/matsu/_font.scss: -------------------------------------------------------------------------------- 1 | $font_large_size: 18px; 2 | $font_normal_size: 100%; 3 | $font_small_size: 12px; 4 | $font_size_title: 20px; 5 | $font_size_2nd_level_title: 16px; 6 | -------------------------------------------------------------------------------- /db/migrate/20170205014850_add_images_to_project.rb: -------------------------------------------------------------------------------- 1 | class AddImagesToProject < ActiveRecord::Migration[4.2] 2 | def change 3 | add_column :projects, :images, :text 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /test/mailers/project_mailer_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class ProjectMailerTest < ActionMailer::TestCase 4 | # test "the truth" do 5 | # assert true 6 | # end 7 | end 8 | -------------------------------------------------------------------------------- /test/models/app_information_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class AppInformationTest < ActiveSupport::TestCase 4 | # test "the truth" do 5 | # assert true 6 | # end 7 | end 8 | -------------------------------------------------------------------------------- /test/models/project_update_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class ProjectUpdateTest < ActiveSupport::TestCase 4 | # test "the truth" do 5 | # assert true 6 | # end 7 | end 8 | -------------------------------------------------------------------------------- /db/migrate/20160605184821_change_column_to_user.rb: -------------------------------------------------------------------------------- 1 | class ChangeColumnToUser < ActiveRecord::Migration[4.2] 2 | def change 3 | change_column :users, :description, :text 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /db/migrate/20161106085544_add_receive_all_to_user.rb: -------------------------------------------------------------------------------- 1 | class AddReceiveAllToUser < ActiveRecord::Migration[4.2] 2 | def change 3 | add_column :users, :receive_all, :bool 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /test/mailers/previews/project_mailer_preview.rb: -------------------------------------------------------------------------------- 1 | # Preview all emails at http://localhost:3000/rails/mailers/project_mailer 2 | class ProjectMailerPreview < ActionMailer::Preview 3 | 4 | end 5 | -------------------------------------------------------------------------------- /config/initializers/mime_types.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Add new mime types for use in respond_to blocks: 4 | # Mime::Type.register "text/richtext", :rtf 5 | -------------------------------------------------------------------------------- /db/migrate/20150426132854_add_index_email_to_users.rb: -------------------------------------------------------------------------------- 1 | class AddIndexEmailToUsers < ActiveRecord::Migration[4.2] 2 | def change 3 | add_index :users, [:email], :unique => true 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /db/migrate/20150429131447_add_index_name_to_skills.rb: -------------------------------------------------------------------------------- 1 | class AddIndexNameToSkills < ActiveRecord::Migration[4.2] 2 | def change 3 | add_index :skills, [:name], :unique => true 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /db/migrate/20160605183055_change_column2_to_project.rb: -------------------------------------------------------------------------------- 1 | class ChangeColumn2ToProject < ActiveRecord::Migration[4.2] 2 | def change 3 | change_column :projects, :description, :text 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /test/models/project_update_history_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class ProjectUpdateHistoryTest < ActiveSupport::TestCase 4 | # test "the truth" do 5 | # assert true 6 | # end 7 | end 8 | -------------------------------------------------------------------------------- /bin/delayed_job: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | require File.expand_path(File.join(File.dirname(__FILE__), '..', 'config', 'environment')) 4 | require 'delayed/command' 5 | Delayed::Command.new(ARGV).daemonize 6 | -------------------------------------------------------------------------------- /db/migrate/20150426045247_remove_delete_flag_from_users.rb: -------------------------------------------------------------------------------- 1 | class RemoveDeleteFlagFromUsers < ActiveRecord::Migration[4.2] 2 | def change 3 | remove_column :users, :delete_flag, :integer 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /app/assets/stylesheets/top.scss: -------------------------------------------------------------------------------- 1 | // Place all the styles related to the top controller here. 2 | // They will automatically be included in application.css. 3 | // You can use Sass (SCSS) here: http://sass-lang.com/ 4 | -------------------------------------------------------------------------------- /app/models/skill.rb: -------------------------------------------------------------------------------- 1 | class Skill < ActiveRecord::Base 2 | has_and_belongs_to_many :users 3 | has_and_belongs_to_many :projects 4 | 5 | def self.skill_members 6 | includes(:users).all 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /db/migrate/20150505071406_add_column_to_project_update.rb: -------------------------------------------------------------------------------- 1 | class AddColumnToProjectUpdate < ActiveRecord::Migration[4.2] 2 | def change 3 | add_column :project_updates, :user_id, :integer 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /db/migrate/20161008063758_add_column_to_project_update2.rb: -------------------------------------------------------------------------------- 1 | class AddColumnToProjectUpdate2 < ActiveRecord::Migration[4.2] 2 | def change 3 | add_column :project_updates, :freezing, :boolean 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /db/migrate/20170205093033_add_image_to_project_update.rb: -------------------------------------------------------------------------------- 1 | class AddImageToProjectUpdate < ActiveRecord::Migration[4.2] 2 | def change 3 | add_column :project_updates, :comment_image, :string 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /Dockerfile.db: -------------------------------------------------------------------------------- 1 | FROM mysql:5.7 2 | 3 | ENV MYSQL_ROOT_PASSWORD 1234 4 | ENV MYSQL_PASSWORD password 5 | ENV MYSQL_DATABASE databasename 6 | 7 | # this need to stay the same for script to work 8 | ENV MYSQL_USER mysql 9 | -------------------------------------------------------------------------------- /db/migrate/20150426045307_remove_delete_flag_from_projects.rb: -------------------------------------------------------------------------------- 1 | class RemoveDeleteFlagFromProjects < ActiveRecord::Migration[4.2] 2 | def change 3 | remove_column :projects, :delete_flag, :integer 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /db/migrate/20150429142635_rename_users_skills_to_skills_users.rb: -------------------------------------------------------------------------------- 1 | class RenameUsersSkillsToSkillsUsers < ActiveRecord::Migration[4.2] 2 | def change 3 | rename_table :users_skills, :skills_users 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /db/migrate/20161002065824_add_project_to_projects.rb: -------------------------------------------------------------------------------- 1 | class AddProjectToProjects < ActiveRecord::Migration[4.2] 2 | def change 3 | add_reference :projects, :project, index: true, foreign_key: true 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /app/assets/stylesheets/sessions.scss: -------------------------------------------------------------------------------- 1 | // Place all the styles related to the sessions controller here. 2 | // They will automatically be included in application.css. 3 | // You can use Sass (SCSS) here: http://sass-lang.com/ 4 | -------------------------------------------------------------------------------- /db/migrate/20160605184658_change_column_to_project_update.rb: -------------------------------------------------------------------------------- 1 | class ChangeColumnToProjectUpdate < ActiveRecord::Migration[4.2] 2 | def change 3 | change_column :project_updates, :description, :text 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /db/migrate/20161203220548_add_last_commented_at_to_project.rb: -------------------------------------------------------------------------------- 1 | class AddLastCommentedAtToProject < ActiveRecord::Migration[4.2] 2 | def change 3 | add_column :projects, :last_commented_at, :datetime 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /app/models/project_update.rb: -------------------------------------------------------------------------------- 1 | class ProjectUpdate < ActiveRecord::Base 2 | belongs_to :project 3 | belongs_to :user 4 | has_many :project_update_histories 5 | mount_uploader :comment_image, CommentImageUploader 6 | end 7 | -------------------------------------------------------------------------------- /db/migrate/20150606234005_remove_column_user.rb: -------------------------------------------------------------------------------- 1 | class RemoveColumnUser < ActiveRecord::Migration[4.2] 2 | def change 3 | remove_column :users, :facebook_user_id 4 | remove_column :users, :password 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /db/migrate/20150614110547_change_column_to_project.rb: -------------------------------------------------------------------------------- 1 | class ChangeColumnToProject < ActiveRecord::Migration[4.2] 2 | def change 3 | change_column :projects, :stage_id, :integer, null: false, default: 1 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /app/views/project_updates/edit.html.erb: -------------------------------------------------------------------------------- 1 |
2 | <% if notice %> 3 | 6 | <% end %> 7 | <%= render 'form' %> 8 |
9 | -------------------------------------------------------------------------------- /app/views/project_updates/new.html.erb: -------------------------------------------------------------------------------- 1 |
2 | <% if notice %> 3 | 6 | <% end %> 7 | <%= render 'form' %> 8 |
9 | -------------------------------------------------------------------------------- /init.sql: -------------------------------------------------------------------------------- 1 | create database if not exists ha4go default character set utf8; 2 | grant ALL on ha4go.* to ha4go@'%' identified by 'ha4goha4go'; 3 | grant ALL on ha4go.* to ha4go@'localhost' identified by 'ha4goha4go'; 4 | flush privileges; 5 | -------------------------------------------------------------------------------- /app/assets/stylesheets/project_updates.scss: -------------------------------------------------------------------------------- 1 | // Place all the styles related to the project_updates controller here. 2 | // They will automatically be included in application.css. 3 | // You can use Sass (SCSS) here: http://sass-lang.com/ 4 | -------------------------------------------------------------------------------- /config/initializers/application_controller_renderer.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # ApplicationController.renderer.defaults.merge!( 4 | # http_host: 'example.org', 5 | # https: false 6 | # ) 7 | -------------------------------------------------------------------------------- /db/migrate/20150426045313_remove_delete_flag_from_project_updates.rb: -------------------------------------------------------------------------------- 1 | class RemoveDeleteFlagFromProjectUpdates < ActiveRecord::Migration[4.2] 2 | def change 3 | remove_column :project_updates, :delete_flag, :integer 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /public/robots.txt: -------------------------------------------------------------------------------- 1 | # See http://www.robotstxt.org/robotstxt.html for documentation on how to use the robots.txt file 2 | # 3 | # To ban all spiders from the entire site uncomment the next two lines: 4 | # User-agent: * 5 | # Disallow: / 6 | -------------------------------------------------------------------------------- /test/controllers/dashboard_controller_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class DashboardControllerTest < ActionController::TestCase 4 | test "should get index" do 5 | get :index 6 | assert_response :success 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /db/migrate/20150607104348_add_index_user_id_to_project_users.rb: -------------------------------------------------------------------------------- 1 | class AddIndexUserIdToProjectUsers < ActiveRecord::Migration[4.2] 2 | def change 3 | add_index :projects_users, [:user_id, :project_id], :unique => true 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /test/controllers/top_controller_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class TopControllerTest < ActionController::TestCase 4 | test "should get index" do 5 | get :index 6 | assert_response :success 7 | end 8 | 9 | end 10 | -------------------------------------------------------------------------------- /.dockerignore: -------------------------------------------------------------------------------- 1 | ### Rails ### 2 | public/assets/* 3 | 4 | ## Environment normalisation: 5 | .bundle 6 | vendor/bundle 7 | bundle 8 | 9 | ## local mount data 10 | mysql/* 11 | 12 | ### EDITOR ### 13 | GTAGS 14 | GRTAGS 15 | GPATH 16 | 17 | log -------------------------------------------------------------------------------- /app/assets/javascripts/top.coffee: -------------------------------------------------------------------------------- 1 | # Place all the behaviors and hooks related to the matching controller here. 2 | # All this logic will automatically be available in application.js. 3 | # You can use CoffeeScript in this file: http://coffeescript.org/ 4 | -------------------------------------------------------------------------------- /app/assets/javascripts/users.coffee: -------------------------------------------------------------------------------- 1 | # Place all the behaviors and hooks related to the matching controller here. 2 | # All this logic will automatically be available in application.js. 3 | # You can use CoffeeScript in this file: http://coffeescript.org/ 4 | -------------------------------------------------------------------------------- /config/initializers/filter_parameter_logging.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Configure sensitive parameters which will be filtered from the log file. 4 | Rails.application.config.filter_parameters += [:password] 5 | -------------------------------------------------------------------------------- /db/migrate/20150429124203_create_skills.rb: -------------------------------------------------------------------------------- 1 | class CreateSkills < ActiveRecord::Migration[4.2] 2 | def change 3 | create_table :skills do |t| 4 | t.string :name 5 | 6 | t.timestamps null: false 7 | end 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /db/migrate/20150614102950_create_stages.rb: -------------------------------------------------------------------------------- 1 | class CreateStages < ActiveRecord::Migration[4.2] 2 | def change 3 | create_table :stages do |t| 4 | t.string :name 5 | 6 | t.timestamps null: false 7 | end 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /app/assets/javascripts/dashboard.coffee: -------------------------------------------------------------------------------- 1 | # Place all the behaviors and hooks related to the matching controller here. 2 | # All this logic will automatically be available in application.js. 3 | # You can use CoffeeScript in this file: http://coffeescript.org/ 4 | -------------------------------------------------------------------------------- /app/assets/javascripts/sessions.coffee: -------------------------------------------------------------------------------- 1 | # Place all the behaviors and hooks related to the matching controller here. 2 | # All this logic will automatically be available in application.js. 3 | # You can use CoffeeScript in this file: http://coffeescript.org/ 4 | -------------------------------------------------------------------------------- /test/fixtures/skills.yml: -------------------------------------------------------------------------------- 1 | # Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html 2 | 3 | one: 4 | name: HTML 5 | 6 | two: 7 | name: CSS 8 | 9 | three: 10 | name: JavaScript 11 | 12 | four: 13 | name: PHP 14 | -------------------------------------------------------------------------------- /Dockerfile.dev: -------------------------------------------------------------------------------- 1 | FROM ruby:2.6.2 2 | RUN apt-get update -qq && apt-get install -y build-essential libpq-dev nodejs 3 | RUN mkdir /myapp 4 | WORKDIR /myapp 5 | ADD Gemfile /myapp/Gemfile 6 | ADD Gemfile.lock /myapp/Gemfile.lock 7 | RUN bundle install 8 | ADD . /myapp 9 | -------------------------------------------------------------------------------- /app/assets/javascripts/project_updates.coffee: -------------------------------------------------------------------------------- 1 | # Place all the behaviors and hooks related to the matching controller here. 2 | # All this logic will automatically be available in application.js. 3 | # You can use CoffeeScript in this file: http://coffeescript.org/ 4 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | # Add your own tasks in files placed in lib/tasks ending in .rake, 2 | # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake. 3 | 4 | require File.expand_path('../config/application', __FILE__) 5 | 6 | Rails.application.load_tasks 7 | -------------------------------------------------------------------------------- /app/controllers/dashboard_controller.rb: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | class DashboardController < ApplicationController 3 | def index 4 | @projects = Project.page(params[:page]) 5 | .per(10) 6 | .order(updated_at: :desc) 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /test/fixtures/stages.yml: -------------------------------------------------------------------------------- 1 | # Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html 2 | 3 | stage_one: 4 | name: 議論と調査 5 | 6 | stage_two: 7 | name: 企画と試作中 8 | 9 | stage_three: 10 | name: 運用中 11 | 12 | stage_four: 13 | name: 休止・終了 14 | -------------------------------------------------------------------------------- /test/fixtures/project_update_histories.yml: -------------------------------------------------------------------------------- 1 | # Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html 2 | 3 | one: 4 | project_update: project_update_one 5 | user: user_one 6 | 7 | two: 8 | project_update_id: project_update_two 9 | user: user_two 10 | -------------------------------------------------------------------------------- /config/initializers/cookies_serializer.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Specify a serializer for the signed and encrypted cookie jars. 4 | # Valid options are :json, :marshal, and :hybrid. 5 | Rails.application.config.action_dispatch.cookies_serializer = :json 6 | -------------------------------------------------------------------------------- /db/migrate/20150429130453_create_users_skills.rb: -------------------------------------------------------------------------------- 1 | class CreateUsersSkills < ActiveRecord::Migration[4.2] 2 | def change 3 | create_table :users_skills do |t| 4 | t.integer :user_id 5 | t.integer :skill_id 6 | 7 | t.timestamps null: false 8 | end 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /db/migrate/20150429143753_create_projects_users.rb: -------------------------------------------------------------------------------- 1 | class CreateProjectsUsers < ActiveRecord::Migration[4.2] 2 | def change 3 | create_table :projects_users do |t| 4 | t.integer :project_id 5 | t.integer :user_id 6 | 7 | t.timestamps null: false 8 | end 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /db/migrate/20150505025435_create_projects_skills.rb: -------------------------------------------------------------------------------- 1 | class CreateProjectsSkills < ActiveRecord::Migration[4.2] 2 | def change 3 | create_table :projects_skills do |t| 4 | t.integer :project_id 5 | t.integer :skill_id 6 | 7 | t.timestamps null: false 8 | end 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /db/migrate/20161106071526_create_app_informations.rb: -------------------------------------------------------------------------------- 1 | class CreateAppInformations < ActiveRecord::Migration[4.2] 2 | def change 3 | create_table :app_informations do |t| 4 | t.date :release 5 | t.text :description 6 | 7 | t.timestamps null: false 8 | end 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /app/views/top/index.html.erb: -------------------------------------------------------------------------------- 1 |
2 | <% if notice %> 3 | 6 | <% end %> 7 | <% @projects.each do |project| %> 8 | <%= render 'shared/project', project: project %> 9 | <% end %> 10 |
11 | -------------------------------------------------------------------------------- /config/locales/views/users/ja.yml: -------------------------------------------------------------------------------- 1 | ja: 2 | users: 3 | index: 4 | members: 登録メンバー一覧 5 | query: 条件を指定して検索 6 | show: 7 | edit: 変更する 8 | edit: 9 | edit: プロフィールを編集する 10 | receive_all: すべての更新をメールで受け取る 11 | form: 12 | new_skill: 上記に無いスキルはスペース区切りでここに入力してください 13 | -------------------------------------------------------------------------------- /test/fixtures/app_informations.yml: -------------------------------------------------------------------------------- 1 | # Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html 2 | 3 | app_information_one: 4 | release: 2016-11-06 5 | description: UIのバージョンアップ、RSSがあることを明示、全更新通知をメールで受け取る設定追加。 6 | app_information_two: 7 | release: 2016-10-02 8 | description: バージョンアップ。 9 | -------------------------------------------------------------------------------- /db/migrate/20150606131655_add_column_to_users.rb: -------------------------------------------------------------------------------- 1 | class AddColumnToUsers < ActiveRecord::Migration[4.2] 2 | def change 3 | add_column :users, :provider, :string 4 | add_column :users, :uid, :string 5 | add_column :users, :oauth_token, :string 6 | add_column :users, :oauth_expires_at, :datetime 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /db/migrate/20160905094440_change_column_to_project2.rb: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | class ChangeColumnToProject2 < ActiveRecord::Migration[4.2] 3 | def up 4 | change_column :projects, :stage_id, :integer, default: 10 5 | end 6 | 7 | def down 8 | change_column :projects, :stage_id, :integer, default: 1 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /test/fixtures/project_updates.yml: -------------------------------------------------------------------------------- 1 | # Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html 2 | 3 | project_update_one: 4 | project: project_one 5 | description: フォロー1 6 | user: user_one 7 | 8 | project_update_two: 9 | project: project_two 10 | description: フォロー2 11 | user: user_two 12 | -------------------------------------------------------------------------------- /app/field_types/array_type.rb: -------------------------------------------------------------------------------- 1 | # https://coderwall.com/p/nnjrlq/multifile-uploads-with-carrierwave 2 | class ArrayType < ActiveRecord::Type::Text 3 | def type_cast(value) 4 | return value if value.instance_of?(Array) 5 | Array.wrap( 6 | YAML.load( 7 | value || YAML.dump([]) 8 | ) 9 | ) 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /db/migrate/20150426043346_create_project_updates.rb: -------------------------------------------------------------------------------- 1 | class CreateProjectUpdates < ActiveRecord::Migration[4.2] 2 | def change 3 | create_table :project_updates do |t| 4 | t.integer :project_id 5 | t.string :description 6 | t.integer :delete_flag 7 | 8 | t.timestamps null: false 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /app/views/shared/_twitter.html: -------------------------------------------------------------------------------- 1 | 4 | -------------------------------------------------------------------------------- /app/views/project_mailer/sendmail_confirm.html.erb: -------------------------------------------------------------------------------- 1 | ProjectMailer#sendmail_confirm 2 | 3 | <%= @greeting %>, find me in app/views/app/views/notice_mailer/sendmail_confirm.html.erb 4 | 5 | <%= t('.here') %> 6 | 7 |

テスト

8 |

あいうえおかきくけこさしすせそたちつてとなにぬねのあいうえおかきくけこさしすせそたちつてとなにぬねのあいうえおかきくけこさしすせそたちつてとなにぬねのあいうえおかきくけこさしすせそたちつてとなにぬねのあいうえおかきくけこさしすせそたちつてとなにぬねのあいうえおかきくけこさしすせそたちつてとなにぬねの

9 | -------------------------------------------------------------------------------- /app/views/shared/_facebook.html: -------------------------------------------------------------------------------- 1 |
2 | 9 | -------------------------------------------------------------------------------- /app/views/project_updates/show.html.erb: -------------------------------------------------------------------------------- 1 |

<%= notice %>

2 | 3 |

4 | Project: 5 | <%= @project_update.project_id %> 6 |

7 | 8 |

9 | Description: 10 | <%= @project_update.description %> 11 |

12 | 13 | <%= link_to 'Edit', edit_project_update_path(@project_update) %> | 14 | <%= link_to 'Back', project_updates_path %> 15 | -------------------------------------------------------------------------------- /db/seeds/projects.yml.sample: -------------------------------------------------------------------------------- 1 | - subject: 議論と調査している課題 2 | description: 議論と調査している課題の説明 3 | stage_id: 10 4 | user_id: 1 5 | - subject: 企画と試作中の課題 6 | description: 企画と試作中の課題の説明 7 | stage_id: 11 8 | user_id: 1 9 | - subject: 運用中の課題 10 | description: 運用中の課題の説明 11 | stage_id: 12 12 | user_id: 1 13 | - subject: 休止・終了の課題 14 | description: 休止・終了の課題の説明 15 | stage_id: 13 16 | user_id: 1 17 | -------------------------------------------------------------------------------- /app/helpers/sns_helper.rb: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | module SnsHelper 3 | def facebook_share_btn(url) 4 | %(
).html_safe 5 | end 6 | 7 | def twitter_share_btn(url) 8 | %(Tweet).html_safe 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /db/migrate/20150426023450_create_users.rb: -------------------------------------------------------------------------------- 1 | class CreateUsers < ActiveRecord::Migration[4.2] 2 | def change 3 | create_table :users do |t| 4 | t.string :name 5 | t.string :email 6 | t.string :password 7 | t.string :description 8 | t.integer :facebook_user_id 9 | t.integer :delete_flag 10 | 11 | t.timestamps null: false 12 | end 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /db/migrate/20161008044105_create_project_update_histories.rb: -------------------------------------------------------------------------------- 1 | class CreateProjectUpdateHistories < ActiveRecord::Migration[4.2] 2 | def change 3 | create_table :project_update_histories do |t| 4 | t.references :project_update, index: true, foreign_key: true 5 | t.references :user, index: true, foreign_key: true 6 | 7 | t.timestamps null: false 8 | end 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /app/assets/stylesheets/projects.scss: -------------------------------------------------------------------------------- 1 | // Place all the styles related to the project controller here. 2 | // They will automatically be included in application.css. 3 | // You can use Sass (SCSS) here: http://sass-lang.com/ 4 | 5 | .project-detail__define { 6 | .row { 7 | margin-bottom: 20px; 8 | &>div:first-child { 9 | font-weight: bold; 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /config/initializers/kaminari_config.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | Kaminari.configure do |config| 3 | config.default_per_page = 10 4 | # config.max_per_page = nil 5 | # config.window = 4 6 | # config.outer_window = 0 7 | # config.left = 0 8 | # config.right = 0 9 | # config.page_method_name = :page 10 | # config.param_name = :page 11 | # config.params_on_first_page = false 12 | end 13 | -------------------------------------------------------------------------------- /test/fixtures/users.yml: -------------------------------------------------------------------------------- 1 | # Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html 2 | 3 | user_one: 4 | name: ユーザ名1 5 | email: sample@sample.com 6 | description: 説明文です 7 | provider: facebook 8 | uid: 1 9 | image: '' 10 | 11 | user_two: 12 | name: ユーザ名2 13 | email: sample@sample.com 14 | description: 説明文です 15 | provider: facebook 16 | uid: 2 17 | image: '' 18 | -------------------------------------------------------------------------------- /config/locales/views/project_mailer/ja.yml: -------------------------------------------------------------------------------- 1 | ja: 2 | project_mailer: 3 | tell_create: 4 | create: 新しい課題「%{project}」ができました。 5 | created_by: '%{name}さんによる作成です。' 6 | tell_update: 7 | update: 課題「%{project}」に更新がありました。 8 | update_by: '%{name}さんによる更新です。' 9 | sendmail_confirm: 10 | here: こちら 11 | tell_skill_match: 12 | need: 課題「%{project}」があなたのスキルとマッチしました。 13 | -------------------------------------------------------------------------------- /db/migrate/20150426023934_create_projects.rb: -------------------------------------------------------------------------------- 1 | class CreateProjects < ActiveRecord::Migration[4.2] 2 | def change 3 | create_table :projects do |t| 4 | t.integer :user_id 5 | t.integer :stage_id 6 | t.string :subject 7 | t.string :description 8 | t.string :user_url 9 | t.string :development_url 10 | t.integer :delete_flag 11 | 12 | t.timestamps null: false 13 | end 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /app/assets/stylesheets/matsu/_color.scss: -------------------------------------------------------------------------------- 1 | $main_theme_color: #F7931E; 2 | $main_bg_color: #f3f3f3; 3 | $title_bg_color: #333; 4 | $title_font_color: #fff; 5 | $contents_bg_color: #fff; 6 | $button_color: $main_theme_color; 7 | $button_color2: #218BBF; 8 | $font_color_on_button: #fff; 9 | $font_color_link: #218BBF; 10 | $font_color_content_title: $font_color_link; 11 | $title_contents_separator_color: #e6e6e6; 12 | $button_disabled_color: #e6e6e6; 13 | -------------------------------------------------------------------------------- /app/controllers/top_controller.rb: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | 3 | # Page Top 4 | class TopController < ApplicationController 5 | LIMIT_ROWS = 10 # プロジェクト表示件数 6 | 7 | def index 8 | @projects = Project.last(LIMIT_ROWS).reverse 9 | end 10 | 11 | def help 12 | end 13 | 14 | def feed 15 | @projects = Project.last(LIMIT_ROWS).reverse 16 | respond_to do |format| 17 | format.rss { render layout: false } 18 | end 19 | end 20 | end 21 | -------------------------------------------------------------------------------- /config/initializers/backtrace_silencers.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces. 4 | # Rails.backtrace_cleaner.add_silencer { |line| line =~ /my_noisy_library/ } 5 | 6 | # You can also remove all the silencers if you're trying to debug a problem that might stem from framework code. 7 | # Rails.backtrace_cleaner.remove_silencers! 8 | -------------------------------------------------------------------------------- /Dockerfile.front: -------------------------------------------------------------------------------- 1 | FROM ha4go-base:1.0 2 | 3 | RUN mkdir /myapp 4 | WORKDIR /myapp 5 | 6 | RUN apt-get install -y libmagickwand-dev tzdata 7 | 8 | ADD Gemfile Gemfile 9 | ADD Gemfile.lock Gemfile.lock 10 | RUN bundle config without test development doc 11 | RUN bundle install 12 | ADD . /myapp/ 13 | 14 | # ADD .env /myapp/.env 15 | ENV RAILS_ENV production 16 | 17 | EXPOSE 3000 18 | 19 | CMD bash -l -c 'bundle exec rake assets:precompile && bundle exec rails s' 20 | -------------------------------------------------------------------------------- /test/fixtures/projects.yml: -------------------------------------------------------------------------------- 1 | # Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html 2 | 3 | project_one: 4 | user: user_one 5 | stage: stage_one 6 | subject: MyString 7 | description: MyString 8 | user_url: MyString 9 | development_url: MyString 10 | 11 | project_two: 12 | user: user_two 13 | stage: stage_two 14 | subject: MyString 15 | description: MyString 16 | user_url: MyString 17 | development_url: MyString 18 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: ruby 2 | rvm: 3 | - 2.3.3 4 | services: 5 | - mysql 6 | 7 | bundler_args: "--without development --deployment" 8 | 9 | cache: bundler 10 | 11 | before_script: 12 | - mysql -e 'create database myapp_test character set utf8;' 13 | - cp config/database.travis.yml config/database.yml 14 | - bundle exec rails db:create 15 | - bundle exec rails db:migrate 16 | script: 17 | - bundle exec rubocop --fail-level=W 18 | - bundle exec rails test 19 | -------------------------------------------------------------------------------- /lib/tasks/unlock_yml.rake: -------------------------------------------------------------------------------- 1 | namespace :db do 2 | namespace :seed do 3 | desc 'Rename db/seeds/*.yml.sample to db/seeds/*.yml' 4 | task unlock_yml: :environment do 5 | samples = Rails.root.join('db', 'seeds', '*.yml.sample') 6 | Dir.glob(samples).each do |sample| 7 | file_name = File.basename(sample, File.extname(sample)) 8 | FileUtils.cp(sample, Rails.root.join('db', 'seeds', file_name), verbose: true) 9 | end 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /app/views/projects/edit.html.erb: -------------------------------------------------------------------------------- 1 | <%= provide(:title, t('title.projects.edit', name: @project.subject)) %> 2 | 3 |
4 | <% if notice %> 5 | 8 | <% end %> 9 | <%= render 'form' %> 10 | <%= link_to @project do %> 11 | 14 | <% end %> 15 |
16 | -------------------------------------------------------------------------------- /app/views/projects/index.html.erb: -------------------------------------------------------------------------------- 1 | <%= provide(:title, t('title.projects.index')) %> 2 | 3 |
4 | <% if notice %> 5 | 8 | <% end %> 9 |
<%= @list_type %>
10 | 11 | <% @projects.each do |project| %> 12 | <%= render 'shared/project', project: project %> 13 | <% end %> 14 |
15 | <%= paginate @projects %> 16 |
17 |
18 | -------------------------------------------------------------------------------- /app/controllers/sessions_controller.rb: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | class SessionsController < ApplicationController 3 | def create 4 | user = User.from_omniauth(request.env["omniauth.auth"]) 5 | session[:user_id] = user.id 6 | redirect_to session[:current_url], notice: "ログインしました" 7 | end 8 | 9 | def destroy 10 | session[:user_id] = nil 11 | redirect_to root_url, notice: "ログアウトしました" 12 | end 13 | 14 | # overrideしてこのコントローラではURLを保存しないようにする 15 | def save_current_url 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /config/initializers/omniauth.rb: -------------------------------------------------------------------------------- 1 | OmniAuth.config.logger = Rails.logger 2 | 3 | Rails.application.config.middleware.use OmniAuth::Builder do 4 | provider :facebook, 5 | ENV['FACEBOOK_APP_ID'], 6 | ENV['FACEBOOK_APP_SECRET'], 7 | client_options: { 8 | site: 'https://graph.facebook.com/v2.8', 9 | authorize_url: "https://www.facebook.com/v2.8/dialog/oauth" 10 | }, 11 | secure_image_url: true, 12 | image_siez: :large 13 | end 14 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '2' 2 | services: 3 | db: 4 | build: 5 | context: . 6 | dockerfile: Dockerfile.db 7 | volumes: 8 | - ./mysql:/var/lib/mysql 9 | ports: 10 | - "3306:3306" 11 | web: 12 | build: 13 | context: . 14 | dockerfile: Dockerfile.dev 15 | command: bundle exec rails s -p 3000 -b '0.0.0.0' 16 | volumes: 17 | - .:/myapp 18 | ports: 19 | - "3000:3000" 20 | depends_on: 21 | - db 22 | environment: 23 | MYSQL_HOST: db -------------------------------------------------------------------------------- /bin/spring: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | # This file loads spring without using Bundler, in order to be fast. 4 | # It gets overwritten when you run the `spring binstub` command. 5 | 6 | unless defined?(Spring) 7 | require "rubygems" 8 | require "bundler" 9 | 10 | if match = Bundler.default_lockfile.read.match(/^GEM$.*?^ (?: )*spring \((.*?)\)$.*?^$/m) 11 | Gem.paths = { "GEM_PATH" => [Bundler.bundle_path.to_s, *Gem.path].uniq } 12 | gem "spring", match[1] 13 | require "spring/binstub" 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /test/test_helper.rb: -------------------------------------------------------------------------------- 1 | ENV['RAILS_ENV'] ||= 'test' 2 | require File.expand_path('../../config/environment', __FILE__) 3 | require 'rails/test_help' 4 | 5 | class ActiveSupport::TestCase 6 | # Setup all fixtures in test/fixtures/*.yml for all tests in alphabetical order. 7 | fixtures :all 8 | 9 | # Add more helper methods to be used by all tests here... 10 | OmniAuth.config.test_mode = true 11 | OmniAuth.config.mock_auth[:facebook] = OmniAuth::AuthHash.new(provider: 'facebook', uid: '12345', info: { name: '山田 太郎' }) 12 | end 13 | -------------------------------------------------------------------------------- /.rubocop_todo.yml: -------------------------------------------------------------------------------- 1 | # This configuration was generated by `rubocop --auto-gen-config` 2 | # on 2014-08-13 13:39:46 +0900 using RuboCop version 0.24.1. 3 | # The point is for the user to remove these configuration records 4 | # one by one as the offenses are removed from the code base. 5 | # Note that changes in the inspected code, or installation of new 6 | # versions of RuboCop, may require this file to be generated again. 7 | 8 | Style/Documentation: 9 | Enabled: false 10 | 11 | Style/LeadingCommentSpace: 12 | Enabled: false 13 | 14 | Style/Next: 15 | Enabled: false 16 | -------------------------------------------------------------------------------- /config/initializers/wrap_parameters.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # This file contains settings for ActionController::ParamsWrapper which 4 | # is enabled by default. 5 | 6 | # Enable parameter wrapping for JSON. You can disable this by setting :format to an empty array. 7 | ActiveSupport.on_load(:action_controller) do 8 | wrap_parameters format: [:json] 9 | end 10 | 11 | # To enable root element in JSON for ActiveRecord objects. 12 | # ActiveSupport.on_load(:active_record) do 13 | # self.include_root_in_json = true 14 | # end 15 | -------------------------------------------------------------------------------- /app/helpers/seo_helper.rb: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | module SeoHelper 3 | def default_meta_tags 4 | { 5 | description: "課題を深く知る市民とシビックテックの情報交換サイト、はじめました。", 6 | og: { 7 | title: 'Ha4go', 8 | site_name: 'Ha4go', 9 | type: 'article', 10 | url: request.url, 11 | description: '課題を深く知る市民とシビックテックの情報交換サイト、はじめました。', 12 | locale: 'ja_jp', 13 | image: request.protocol + request.host + asset_path('ha4go_icon.png') 14 | }, 15 | fb: { 16 | app_id: ENV['FACEBOOK_APP_ID'] 17 | } 18 | } 19 | end 20 | end 21 | -------------------------------------------------------------------------------- /config/locales/ja.yml: -------------------------------------------------------------------------------- 1 | ja: 2 | helpers: 3 | page_entries_info: 4 | more_pages: 5 | display_entries: "%{total}中の%{entry_name}を表示しています %{first} - %{last}" 6 | one_page: 7 | display_entries: 8 | one: "%{count}レコード表示中です %{entry_name}" 9 | other: "%{count}レコード表示中です %{entry_name}" 10 | zero: "レコードが見つかりませんでした %{entry_name}" 11 | views: 12 | pagination: 13 | first: "« 最初" 14 | last: "最後 »" 15 | next: "次 ›" 16 | previous: "‹ 前" 17 | truncate: "…" 18 | -------------------------------------------------------------------------------- /config/locales/views/dashboard/ja.yml: -------------------------------------------------------------------------------- 1 | ja: 2 | dashboard: 3 | need_login: You Need to Login 4 | index: 5 | dashboard: ダッシュボード 6 | title: Ha4go へようこそ 7 | project_button: 課題を作成して募集・議論を開始する 8 | register_button: 応募・議論のためにスキルを登録する 9 | need_login: You Need to Login 10 | created_by_you: あなたの作成した課題の更新状況 11 | you_joined: あなたの参加している課題の更新状況 12 | your_comment: あなたのコメント 13 | max: '(最新%{count}件ごと)' 14 | match_your_skill: あなたのスキルにマッチした課題 15 | inviting: で募集中 16 | all_project: 全ての課題の更新状況 17 | -------------------------------------------------------------------------------- /test/controllers/sessions_controller_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class SessionsControllerTest < ActionController::TestCase 4 | setup do 5 | @controller.session['current_url'] = '/' 6 | @request.env['omniauth.auth'] = OmniAuth.config.mock_auth[:facebook] 7 | end 8 | test "should get create" do 9 | get :create 10 | assert_response :redirect 11 | assert_redirected_to @controller.session['current_url'] 12 | end 13 | 14 | test "should get destroy" do 15 | get :destroy 16 | assert_response :redirect 17 | assert_redirected_to root_url 18 | end 19 | 20 | end 21 | -------------------------------------------------------------------------------- /app/views/shared/_ogp_project.html.erb: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | /> 10 | -------------------------------------------------------------------------------- /app/assets/stylesheets/bootstrap_override.scss: -------------------------------------------------------------------------------- 1 | @font-face{ 2 | font-family:'Glyphicons Halflings'; 3 | src: image-url("bootstrap/glyphicons-halflings-regular.eot"); 4 | src: image-url("bootstrap/glyphicons-halflings-regular.eot?#iefix") format("embedded-opentype"), 5 | image-url("bootstrap/glyphicons-halflings-regular.woff") format("woff"), 6 | image-url("bootstrap/glyphicons-halflings-regular.ttf") format("truetype"), 7 | image-url("bootstrap/glyphicons-halflings-regular.svg#glyphicons_halflingsregular") format("svg") 8 | } 9 | 10 | .navbar-inverse{ 11 | background-color: #F7931E; 12 | color: #FFFFFF; 13 | } -------------------------------------------------------------------------------- /app/views/projects/new.html.erb: -------------------------------------------------------------------------------- 1 | <%= provide(:title, t('title.projects.new')) %> 2 | 3 |
4 | <% if notice %> 5 | 8 | <% end %> 9 |
10 | <% unless @parent_project.nil? %> 11 |
12 |
13 | <%= t 'dic.parent_project' %> 14 |
15 |
16 | <%= @parent_project.subject %> 17 |
18 |
19 | <% end %> 20 |
21 | <%= render 'form' %> 22 |
23 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files for more about ignoring files. 2 | # 3 | # If you find yourself ignoring temporary files generated by your text editor 4 | # or operating system, you probably want to add a global ignore instead: 5 | # git config --global core.excludesfile '~/.gitignore_global' 6 | 7 | # Ignore bundler config. 8 | /.bundle 9 | 10 | # Ignore the default SQLite database. 11 | /db/*.sqlite3 12 | /db/*.sqlite3-journal 13 | 14 | # Ignore all logfiles and tempfiles. 15 | /log/* 16 | !/log/.keep 17 | /tmp 18 | /vendor/bundle 19 | /.env* 20 | 21 | /mysql/* 22 | 23 | /public/uploads/* 24 | db/seeds/*.yml 25 | -------------------------------------------------------------------------------- /app/controllers/concerns/sns_publisher.rb: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | module SnsPublisher 3 | extend ActiveSupport::Concern 4 | 5 | def project_publish_to_sns_page(text, project_record, updater_record) 6 | publish_to_sns_page( 7 | text, 8 | project_path(project_record.id), 9 | project_record.subject, 10 | project_record.description, 11 | updater_record.image 12 | ) 13 | end 14 | 15 | protected 16 | 17 | def publish_to_sns_page(text, uri, name, description, image) 18 | return if ENV['FACEBOOK_PAGE_SECRET_TOKEN'].nil? 19 | PostToSnsJob.perform_later(text, uri, name, description, image) 20 | end 21 | end 22 | -------------------------------------------------------------------------------- /app/views/shared/_ogp_common.html.erb: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | /> 11 | -------------------------------------------------------------------------------- /app/assets/stylesheets/users.scss: -------------------------------------------------------------------------------- 1 | // Place all the styles related to the user controller here. 2 | // They will automatically be included in application.css. 3 | // You can use Sass (SCSS) here: http://sass-lang.com/ 4 | 5 | .user-search__button { 6 | margin-top: 20px; 7 | } 8 | 9 | .user-list__box { 10 | margin-top: 30px; 11 | } 12 | 13 | .user-list__name { 14 | margin-top: 15px; 15 | font-size: 24px; 16 | } 17 | 18 | .user-detail__list { 19 | margin-top: 20px; 20 | } 21 | 22 | .user-edit { 23 | .row { 24 | margin-bottom: 20px; 25 | 26 | &>div:first-child { 27 | font-weight: bold; 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /misc/docker/heroku-deploy/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM debian:jessie 2 | 3 | MAINTAINER PharaohKJ 4 | 5 | RUN export DEBIAN_FRONTEND=noninteractive LANG 6 | RUN apt-get update && apt-get upgrade -y 7 | RUN apt-get install -y git ruby make ssh wget sudo apt-utils 8 | RUN apt-get clean 9 | RUN wget -qO- https://toolbelt.heroku.com/install-ubuntu.sh | sh 10 | RUN mkdir ~/.ssh && chmod og-rw ~/.ssh && ssh-keyscan github.com > ~/.ssh/known_hosts 11 | ADD ./heroku_login heroku_login 12 | RUN heroku auth:login < heroku_login 13 | RUN git clone -b develop https://github.com/jshimazu/ha4go.git 14 | RUN cd ha4go && heroku git:remote -a ha4go-develop 15 | CMD "/bin/bash" 16 | -------------------------------------------------------------------------------- /app/views/project_mailer/tell_skill_match.html.erb: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 |

<%= t('.need', project: @project.subject)%>

8 | <%= t('mail.link_head')%> <%= link_to( t('mail.here'), project_url(id: @project.id), only_path: false) %> <%= t('mail.link_foot')%> 9 |
10 | <%= t('mail.dont_res') %> 11 |
12 |
13 |
14 | <%= description_text(@project.description, 255) %> 15 |
16 |
17 |
18 | <%= t('mail.miss')%> 19 |
20 |
21 | <%= t('mail.footer')%> 22 |
23 | 24 | 25 | -------------------------------------------------------------------------------- /app/assets/javascripts/facebook.js.coffee.erb: -------------------------------------------------------------------------------- 1 | jQuery -> 2 | 3 | $.ajax 4 | url: "#{window.location.protocol}//connect.facebook.net/en_US/all.js" 5 | dataType: 'script' 6 | cache: true 7 | 8 | 9 | window.fbAsyncInit = -> 10 | FB.init(appId: '<%= ENV["FACEBOOK_APP_ID"] %>', cookie: true, status: true, xfbml: true, version: 'v2.9') 11 | 12 | $('#sign_in').click (e) -> 13 | e.preventDefault() 14 | FB.login (response) -> 15 | window.location = '/auth/facebook/callback' if response.authResponse 16 | 17 | $('#sign_out').click (e) -> 18 | FB.getLoginStatus (response) -> 19 | FB.logout() if response.authResponse 20 | true 21 | 22 | $('body').prepend('
') 23 | -------------------------------------------------------------------------------- /app/assets/javascripts/projects.coffee: -------------------------------------------------------------------------------- 1 | # Place all the behaviors and hooks related to the matching controller here. 2 | # All this logic will automatically be available in application.js. 3 | # You can use CoffeeScript in this file: http://coffeescript.org/ 4 | 5 | $ -> 6 | $('body').on 'click', '#agree_message_check', -> 7 | if ($("#agree_message_check").prop("checked")) 8 | $("#need_agree_button").prop("disabled", false); 9 | else 10 | $("#need_agree_button").prop("disabled", true); 11 | 12 | $ -> 13 | $('body').on 'click', '#write_comment', -> 14 | $('#write_comment').hide() 15 | $('#add_comment').show() 16 | -------------------------------------------------------------------------------- /config/initializers/assets.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Version of your assets, change this if you want to expire all your assets. 4 | Rails.application.config.assets.version = '1.0' 5 | 6 | # Add additional assets to the asset load path 7 | # Rails.application.config.assets.paths << Emoji.images_path 8 | 9 | # Precompile additional assets. 10 | # application.js, application.css, and all non-JS/CSS in app/assets folder are already added. 11 | # Rails.application.config.assets.precompile += %w( search.js ) 12 | 13 | Rails.application.config.assets.paths << "#{Rails}/vendor/assets/fonts" 14 | Rails.application.config.assets.precompile += %w( jquery.js bootstrap.js jquery_ujs.js matsu/*) 15 | -------------------------------------------------------------------------------- /config/database.yml: -------------------------------------------------------------------------------- 1 | # SQLite version 3.x 2 | # gem install sqlite3 3 | # 4 | # Ensure the SQLite 3 gem is defined in your Gemfile 5 | # gem 'sqlite3' 6 | # 7 | default: &default 8 | adapter: mysql2 9 | encoding: utf8 10 | pool: 5 11 | database: <%= ENV['DATABASE_NAME'] %> 12 | username: <%= ENV['MYSQL_USER'] %> 13 | password: <%= ENV['MYSQL_PW'] %> 14 | host: <%= ENV['MYSQL_HOST'] %> 15 | timeout: 5000 16 | 17 | development: 18 | <<: *default 19 | 20 | test: 21 | <<: *default 22 | database: <%= ENV['TEST_DATABASE_NAME'] %> 23 | username: <%= ENV['TEST_MYSQL_USER'] %> 24 | password: <%= ENV['TEST_MYSQL_PW'] %> 25 | host: <%= ENV['TEST_MYSQL_HOST'] %> 26 | 27 | production: 28 | <<: *default 29 | -------------------------------------------------------------------------------- /config/initializers/inflections.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Add new inflection rules using the following format. Inflections 4 | # are locale specific, and you may define rules for as many different 5 | # locales as you wish. All of these examples are active by default: 6 | # ActiveSupport::Inflector.inflections(:en) do |inflect| 7 | # inflect.plural /^(ox)$/i, '\1en' 8 | # inflect.singular /^(ox)en/i, '\1' 9 | # inflect.irregular 'person', 'people' 10 | # inflect.uncountable %w( fish sheep ) 11 | # end 12 | 13 | # These inflection rules are supported but not enabled by default: 14 | # ActiveSupport::Inflector.inflections(:en) do |inflect| 15 | # inflect.acronym 'RESTful' 16 | # end 17 | -------------------------------------------------------------------------------- /app/views/project_mailer/tell_create.html.erb: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 |

<%= t('.create', project: @project.subject)%>

8 | <%= t('.created_by', name: @project.user.name) %> 9 | <%= t('mail.link_head')%> <%= link_to( t('mail.here'), project_url(id: @project.id), only_path: false) %> <%= t('mail.link_foot')%> 10 |
11 | <%= t('mail.dont_res') %> 12 |
13 |
14 |
15 | <%= description_text(@project.description, 255) %> 16 |
17 |
18 |
19 | <%= t('mail.miss')%> 20 |
21 |
22 | <%= t('mail.footer')%> 23 |
24 | 25 | 26 | -------------------------------------------------------------------------------- /app/views/users/edit.html.erb: -------------------------------------------------------------------------------- 1 | <%= provide(:title, t('title.users.edit')) %> 2 | 3 |
4 | <% if notice %> 5 | 8 | <% end %> 9 | <%= render 'form' %> 10 | <% if @from == 'dashboard' %> 11 | <%= link_to dashboard_path do %> 12 | 15 | <% end %> 16 | <% else %> 17 | <%= link_to @user do %> 18 | 21 | <% end %> 22 | <% end %> 23 |
24 | -------------------------------------------------------------------------------- /app/assets/javascripts/application.js: -------------------------------------------------------------------------------- 1 | // This is a manifest file that'll be compiled into application.js, which will include all the files 2 | // listed below. 3 | // 4 | // Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts, 5 | // or any plugin's vendor/assets/javascripts directory can be referenced here using a relative path. 6 | // 7 | // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the 8 | // compiled file. 9 | // 10 | // Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details 11 | // about supported directives. 12 | // 13 | //= require jquery 14 | //= require matsu/jquery.mobile-menu 15 | //= require jquery_ujs 16 | //= require bootstrap.min 17 | //= require_tree . 18 | -------------------------------------------------------------------------------- /app/views/project_updates/_form.html.erb: -------------------------------------------------------------------------------- 1 | <%= form_for(@project_update) do |f| %> 2 | <% if @project_update.errors.any? %> 3 |
4 |

<%= pluralize(@project_update.errors.count, "error") %> prohibited this project_update from being saved:

5 | 6 | 11 |
12 | <% end %> 13 | 14 | <%= f.hidden_field :project_id, value: params[:project_id] %> 15 |
16 | <%= f.text_area :description, class: 'form-control', rows: 10 %> 17 |
18 | 21 | <% end %> 22 | -------------------------------------------------------------------------------- /app/views/project_mailer/tell_update.html.erb: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 |

<%= t('.update', project: @project_update.project.subject.truncate(25)) %>

8 |
9 | <%= t('.update_by', name: @project_update.user.name) %> 10 | <%= t('mail.link_head')%> <%= link_to( t('mail.here'), project_url(id: @project_update.project.id), only_path: false) %> <%= t('mail.link_foot')%> 11 |
12 |
13 | <%= t('mail.dont_res') %> 14 |
15 |
16 |
17 | <%= description_text(@project_update.description.truncate(255)) %> 18 |
19 |
20 |
21 | <%= t('mail.miss') %> 22 |
23 |
24 | <%= t('mail.footer')%> 25 |
26 | 27 | 28 | -------------------------------------------------------------------------------- /test/controllers/users_controller_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class UsersControllerTest < ActionController::TestCase 4 | setup do 5 | @user = users(:user_one) 6 | end 7 | 8 | test "should get index" do 9 | get :index 10 | assert_response :success 11 | assert_not_nil assigns(:users) 12 | end 13 | 14 | test "should show user" do 15 | get :show, params: { id: @user } 16 | assert_response :success 17 | end 18 | 19 | test "should get edit" do 20 | get :edit, params: { id: @user } 21 | assert_response :success 22 | end 23 | 24 | test "should update user" do 25 | patch :update, params: { id: @user, user: { description: @user.description, email: @user.email, name: @user.name }, skill_names: { skill_ids: [] }, new_skills: { new_skills: '' } } 26 | assert_redirected_to user_path(assigns(:user)) 27 | end 28 | end 29 | -------------------------------------------------------------------------------- /.env.sample: -------------------------------------------------------------------------------- 1 | FACEBOOK_APP_ID=12341234 2 | FACEBOOK_APP_SECRET="hogehogehoge" 3 | DELIVERY_METHOD=letter_opener_web 4 | SMTP_SERVER='smtp.gmail.com' 5 | SMTP_PORT=587 6 | SMTP_DOMAIN='googleapps.domain' 7 | SMTP_USER='notifier_user@googleapps.domain' 8 | SMTP_PASSWORD='password_of_notifier_user' 9 | APP_HOST=localhost:3000 10 | MYSQL_HOST=127.0.0.1 11 | MYSQL_USER=ha4go 12 | MYSQL_PW=ha4goha4go 13 | DATABASE_NAME=ha4go 14 | # PRODUCTION_DATABASE_NAME_=ha4go_dev 15 | # MYSQL_PRODUCTION_HOST=db 16 | # MYSQL_PRODUCTION_USER=user 17 | # MYSQL_PRODUCTION_PW=hogehoge 18 | USE_HTTPS=0 19 | LINK_ABOUT_PROJECT_STATUS=https://github.com/codeforkanazawa-org/ha4go/wiki/%E8%AA%B2%E9%A1%8C%E3%81%AE%E3%82%B9%E3%83%86%E3%83%BC%E3%82%BF%E3%82%B9 20 | LINK_USER_TERMS=https://github.com/codeforkanazawa-org/ha4go/wiki/ha4go-%E5%88%A9%E7%94%A8%E8%A6%8F%E7%B4%84 21 | FACEBOOK_PAGE_SECRET_TOKEN = FACEBOOK_PAGE_SECRET_TOKEN 22 | -------------------------------------------------------------------------------- /bin/update: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require 'pathname' 3 | require 'fileutils' 4 | include FileUtils 5 | 6 | # path to your application root. 7 | APP_ROOT = Pathname.new File.expand_path('../../', __FILE__) 8 | 9 | def system!(*args) 10 | system(*args) || abort("\n== Command #{args} failed ==") 11 | end 12 | 13 | chdir APP_ROOT do 14 | # This script is a way to update your development environment automatically. 15 | # Add necessary update steps to this file. 16 | 17 | puts '== Installing dependencies ==' 18 | system! 'gem install bundler --conservative' 19 | system('bundle check') || system!('bundle install') 20 | 21 | puts "\n== Updating database ==" 22 | system! 'bin/rails db:migrate' 23 | 24 | puts "\n== Removing old logs and tempfiles ==" 25 | system! 'bin/rails log:clear tmp:clear' 26 | 27 | puts "\n== Restarting application server ==" 28 | system! 'bin/rails restart' 29 | end 30 | -------------------------------------------------------------------------------- /app/views/project_updates/index.html.erb: -------------------------------------------------------------------------------- 1 |

<%= notice %>

2 | 3 |

Listing Project Updates

4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | <% @project_updates.each do |project_update| %> 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | <% end %> 25 | 26 |
ProjectDescriptionDelete flag
<%= project_update.project_id %><%= project_update.description %><%= link_to 'Show', project_update %><%= link_to 'Edit', edit_project_update_path(project_update) %><%= link_to 'Destroy', project_update, method: :delete, data: { confirm: 'Are you sure?' } %>
27 | 28 |
29 | 30 | <%= link_to 'New Project update', new_project_update_path %> 31 | -------------------------------------------------------------------------------- /config/initializers/carrierwave.rb: -------------------------------------------------------------------------------- 1 | require 'carrierwave/storage/abstract' 2 | require 'carrierwave/storage/file' 3 | require 'carrierwave/storage/fog' 4 | 5 | if Rails.env.production? && ENV['STORAGE_SERVICE'] == 'amazon-s3' 6 | CarrierWave.configure do |config| 7 | config.storage = :fog 8 | config.fog_provider = 'fog/aws' 9 | config.fog_credentials = { 10 | :provider => 'AWS', 11 | :aws_access_key_id => ENV['S3_ACCESS_KEY_ID'], 12 | :aws_secret_access_key => ENV['S3_SECRET_KEY_ID'], 13 | :region => ENV['S3_REGION'] 14 | } 15 | 16 | config.fog_directory = ENV['S3_BUCKET_NAME'] 17 | config.fog_public = true 18 | config.fog_attributes = {'Cache-Control' => 'public, max-age=86400'} 19 | end 20 | else 21 | CarrierWave.configure do |config| 22 | config.storage = :file 23 | end 24 | end 25 | 26 | CarrierWave::SanitizedFile.sanitize_regexp = /[^[:word:]\.\-\+]/ -------------------------------------------------------------------------------- /config/locales/views/projects/ja.yml: -------------------------------------------------------------------------------- 1 | ja: 2 | projects: 3 | banner: 4 | joined: 課題に参加しました。 5 | leaved: 課題への参加をやめました。 6 | updated: 課題の内容を変更しました。 7 | created: 課題を作成しました。 8 | cannot: 失敗しました。 9 | show: 10 | edit: 編集する 11 | url: URL 12 | github: GitHub URL 13 | creator: 立てた人 14 | member: メンバー 15 | stage: ステージ 16 | skill: 必要なスキル 17 | detail: 詳細 18 | write_comment: フォローを書く 19 | join: 参加を希望する 20 | leave: 参加をやめる 21 | login_recomendation: ログインすることでこの課題に参加できるようになります 22 | login: ログイン 23 | edit: 24 | edit: 課題を編集する 25 | form: 26 | skill: 必要なスキル 27 | new_skill: 上記に無いスキルはスペース区切りでここに入力してください 28 | dev_url: 開発用URL(GitHubのURLなど) 29 | recommend_skill: (必要なスキルをここで登録することで、この Ha4go 登録者全体から、マッチングした方へメールが送付されます。あとで増やすことができます。) 30 | recommend_dev_url: (この課題を実際に解決しようと議論・プロジェクトのページなどあればここで指定してください。) 31 | -------------------------------------------------------------------------------- /app/assets/stylesheets/application.scss: -------------------------------------------------------------------------------- 1 | /* 2 | * This is a manifest file that'll be compiled into application.css, which will include all the files 3 | * listed below. 4 | * 5 | * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets, 6 | * or any plugin's vendor/assets/stylesheets directory can be referenced here using a relative path. 7 | * 8 | * You're free to add application-wide styles to this file and they'll appear at the bottom of the 9 | * compiled file so the styles you add here take precedence over styles defined in any styles 10 | * defined in the other CSS/SCSS files in this directory. It is generally better to create a new 11 | * file per style scope. 12 | * 13 | // * require bootstrap.min 14 | // * require bootstrap_override 15 | *= require matsu/reset 16 | *= require matsu/style 17 | *= require matsu/sp_style 18 | *= require matsu/jquery.mobile.menu 19 | *= require_tree . 20 | *= require_self 21 | */ 22 | -------------------------------------------------------------------------------- /.rubocop.yml: -------------------------------------------------------------------------------- 1 | inherit_from: .rubocop_todo.yml 2 | 3 | require: rubocop-performance 4 | 5 | AllCops: 6 | TargetRubyVersion: 2.6 7 | Exclude: 8 | - 'db/**/*' 9 | - 'config/**/*' 10 | - 'bin/*' 11 | - 'vendor/**/*' 12 | 13 | Style/AsciiComments: 14 | Enabled: false 15 | 16 | Metrics/ClassLength: 17 | Max: 200 18 | 19 | Style/IfUnlessModifier: 20 | Enabled: false 21 | 22 | Metrics/MethodLength: 23 | Max: 50 24 | 25 | Style/PercentLiteralDelimiters: 26 | Enabled: false 27 | 28 | Style/RedundantReturn: 29 | Enabled: false 30 | 31 | #Style/RegexpLiteral: 32 | # MaxSlashes: 2 33 | 34 | Style/SpecialGlobalVars: 35 | Enabled: false 36 | 37 | Style/StringLiterals: 38 | Enabled: false 39 | 40 | #Style/TrailingComma: 41 | # Enabled: false 42 | 43 | Style/UnneededPercentQ: 44 | Enabled: false 45 | 46 | Metrics/AbcSize: 47 | Max: 20 48 | 49 | SignalException: 50 | EnforcedStyle: only_raise 51 | 52 | # "Line is too long"を無効 53 | Metrics/LineLength: 54 | Enabled: false 55 | 56 | Rails: 57 | Enabled: true 58 | -------------------------------------------------------------------------------- /app/views/users/index.html.erb: -------------------------------------------------------------------------------- 1 | <%= provide(:title, t('title.users.index')) %> 2 | 3 |
4 | <% if notice %> 5 | 8 | <% end %> 9 |
<%= t('.members') %>
10 |
11 |
12 | <%= form_tag users_path, :method => 'GET' do %> 13 | <%= select_tag 'skill_id', options_for_select(@options, :selected => params[:skill_id]), :class => 'form-control' %> 14 | 15 | <% end %> 16 |
17 |
18 |
19 |
20 | <% @users.each do |user| %> 21 |
22 |
<%= image_tag(user.image) %>
23 |
<%= name_and_link(user) %>
24 |
25 | <% end %> 26 |
27 |
28 |
29 | -------------------------------------------------------------------------------- /bin/setup: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require 'pathname' 3 | require 'fileutils' 4 | include FileUtils 5 | 6 | # path to your application root. 7 | APP_ROOT = Pathname.new File.expand_path('../../', __FILE__) 8 | 9 | def system!(*args) 10 | system(*args) || abort("\n== Command #{args} failed ==") 11 | end 12 | 13 | chdir APP_ROOT do 14 | # This script is a starting point to setup your application. 15 | # Add necessary setup steps to this file. 16 | 17 | puts '== Installing dependencies ==' 18 | system! 'gem install bundler --conservative' 19 | system('bundle check') || system!('bundle install') 20 | 21 | # puts "\n== Copying sample files ==" 22 | # unless File.exist?('config/database.yml') 23 | # cp 'config/database.yml.sample', 'config/database.yml' 24 | # end 25 | 26 | puts "\n== Preparing database ==" 27 | system! 'bin/rails db:setup' 28 | 29 | puts "\n== Removing old logs and tempfiles ==" 30 | system! 'bin/rails log:clear tmp:clear' 31 | 32 | puts "\n== Restarting application server ==" 33 | system! 'bin/rails restart' 34 | end 35 | -------------------------------------------------------------------------------- /app/jobs/post_to_sns_job.rb: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | class PostToSnsJob < ActiveJob::Base 3 | queue_as :default 4 | 5 | def perform(text, uri, name, description, _image) 6 | # localhost:3000 などでデバッグしていると必ず失敗するので留意すること 7 | # (FBが localhost へのリンクを投稿しようとすると必ず失敗するようになっているようだ) 8 | fb_page = Koala::Facebook::API.new(ENV['FACEBOOK_PAGE_SECRET_TOKEN']) 9 | # params are to see http://www.rubydoc.info/github/arsduo/koala/Koala%2FFacebook%2FGraphAPIMethods%3Aput_wall_post 10 | post_params = { 11 | link: absolute_url(uri), 12 | name: name, 13 | description: description 14 | } 15 | post_params.each do |k, v| 16 | logger.debug("[PUT_WALL_POST] #{k} : #{v}") 17 | end 18 | logger.debug("[PUT_WALL_POST] #{text}") 19 | fb_page.put_wall_post(text, post_params) 20 | true 21 | rescue => e 22 | logger.fatal(e.to_s) 23 | false 24 | end 25 | 26 | def absolute_url(uri) 27 | protocol = 'http' 28 | protocol += 's' if ENV['USE_HTTPS'].to_i > 0 29 | "#{protocol}://#{ENV['APP_HOST']}#{uri}" 30 | end 31 | end 32 | -------------------------------------------------------------------------------- /app/mailers/project_mailer.rb: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | class ProjectMailer < ApplicationMailer 3 | add_template_helper(ApplicationHelper) 4 | default from: ENV['NOTIF_MAIL_FROM'] || ENV['SMTP_USER'] || "ha4go@#{ENV.fetch('APP_HOST') { 'codeforkanazawa.org' }}" 5 | 6 | def tell_create(mails, project) 7 | @project = project 8 | # **TODO** controller support i18n 9 | mail to: mails, subject: '[Ha4go] 課題が作成されました' 10 | end 11 | 12 | def tell_update(mails, project_update) 13 | @project_update = project_update 14 | # **TODO** controller support i18n 15 | mail to: mails, subject: '[Ha4go] 課題に更新がありました' 16 | end 17 | 18 | def tell_skill_match(mails, project, is_new = false) 19 | @project = project 20 | subject = if is_new 21 | '[Ha4go] あなたのスキルにマッチした課題が登録されました' 22 | else 23 | '[Ha4go] あなたのスキルを求めている課題があります' 24 | end 25 | mail to: mails, subject: subject 26 | end 27 | 28 | # test code 29 | def sendmail_confirm 30 | @greeting = 'Hi' 31 | mail to: 'kato@phalanxware.com', subject: 'ActionMailer test' 32 | end 33 | end 34 | -------------------------------------------------------------------------------- /db/seeds/development.rb: -------------------------------------------------------------------------------- 1 | def relative_path(path) 2 | File.join(File.dirname(__FILE__), path) 3 | end 4 | 5 | def read_relative(path) 6 | File.read relative_path path 7 | end 8 | 9 | def load_seed_from_yaml(file_name) 10 | file_path = relative_path(file_name) 11 | return warn "#{file_name} does not exist file." unless File.exist?(file_path) 12 | if block_given? 13 | yml = YAML.load(read_relative(file_name)) 14 | yml.each { |y| yield y } 15 | end 16 | end 17 | 18 | load_seed_from_yaml('users.yml') do |user| 19 | auth = JSON.parse(user.to_json, object_class: OpenStruct) 20 | user = User.from_omniauth(auth) 21 | user.update(email: auth.email, description: "私の名前は #{user.name}") 22 | end 23 | 24 | load_seed_from_yaml('projects.yml') do |project| 25 | params = JSON.parse(project.to_json, object_class: OpenStruct) 26 | project = Project.new( 27 | subject: params.subject, 28 | description: params.description, 29 | stage_id: params.stage_id, 30 | user_id: params.user_id 31 | ) 32 | project.skills << Skill.all 33 | project.users << User.find(params.user_id) 34 | project.save 35 | end 36 | -------------------------------------------------------------------------------- /Dockerfile.base: -------------------------------------------------------------------------------- 1 | FROM ubuntu:18.04 2 | 3 | ENV DEBIAN_FRONTEND noninteractive 4 | 5 | RUN apt-get update && \ 6 | apt-get upgrade -y && \ 7 | apt-get -y install \ 8 | build-essential \ 9 | curl \ 10 | git-core \ 11 | libcurl4-openssl-dev \ 12 | libreadline-dev \ 13 | libssl-dev \ 14 | libxml2-dev \ 15 | libxslt1-dev \ 16 | libyaml-dev \ 17 | zlib1g-dev && \ 18 | curl -O http://ftp.ruby-lang.org/pub/ruby/2.6/ruby-2.6.2.tar.gz && \ 19 | tar -zxvf ruby-2.6.2.tar.gz && \ 20 | cd ruby-2.6.2 && \ 21 | ./configure --disable-install-doc && \ 22 | make && \ 23 | make install && \ 24 | cd .. && \ 25 | rm -r ruby-2.6.2 ruby-2.6.2.tar.gz && \ 26 | echo 'gem: --no-document' > /usr/local/etc/gemrc 27 | 28 | # Install Bundler for each version of ruby 29 | RUN \ 30 | echo 'gem: --no-rdoc --no-ri' >> /.gemrc && \ 31 | gem install bundler 32 | 33 | # install sqlite3 34 | RUN apt-get install -y sqlite3 libsqlite3-dev 35 | 36 | RUN apt-get install -y libmysqld-dev libpq-dev 37 | 38 | # Install Node.js and npm 39 | RUN \ 40 | apt-get update && \ 41 | apt-get install -y nodejs 42 | -------------------------------------------------------------------------------- /app/assets/stylesheets/dashboard.scss: -------------------------------------------------------------------------------- 1 | @import "matsu/color"; 2 | @import "matsu/font"; 3 | 4 | .content_box { 5 | padding: 15px; 6 | clear: both; 7 | font-size: 14px; 8 | } 9 | 10 | .dashboard_content_box { 11 | @extend .content_box; 12 | border-bottom: 1px solid $title_contents_separator_color; 13 | font-size: $font_small_size; 14 | img { 15 | height: 20px; 16 | border-radius: 10px; 17 | } 18 | } 19 | 20 | .create_project_title { 21 | padding: 10px 4%; 22 | color: $font_color_on_button; 23 | font-size: $font_large_size; 24 | background-color: $button_color; 25 | border: 1px solid $button_color; 26 | border-radius: 10px; 27 | vertical-align: middle; 28 | margin: 20px; 29 | } 30 | 31 | .large_button { 32 | vertical-align: middle; 33 | margin-right: 15px; 34 | } 35 | 36 | .large_button_text { 37 | vertical-align: middle; 38 | } 39 | 40 | .register_user_title { 41 | @extend .create_project_title; 42 | background-color: $button_color2; 43 | border: 1px solid $button_color2; 44 | } 45 | 46 | .project_update_list { 47 | width: 90%; 48 | background-color: $contents_bg_color; 49 | margin-bottom: 20px; 50 | } 51 | -------------------------------------------------------------------------------- /app/assets/images/Feed-icon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /config/application.rb: -------------------------------------------------------------------------------- 1 | require_relative 'boot' 2 | 3 | require 'rails/all' 4 | 5 | # Require the gems listed in Gemfile, including any gems 6 | # you've limited to :test, :development, or :production. 7 | Bundler.require(*Rails.groups) 8 | 9 | module Ha4go 10 | class Application < Rails::Application 11 | # Settings in config/environments/* take precedence over those specified here. 12 | # Application configuration should go into files in config/initializers 13 | # -- all .rb files in that directory are automatically loaded. 14 | config.time_zone = 'Tokyo' 15 | config.active_record.default_timezone = :local 16 | # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded. 17 | config.i18n.load_path += Dir[Rails.root.join('config', 'locales', '**', '*.{rb,yml}').to_s] 18 | 19 | I18n.available_locales = [:en, :ja] 20 | I18n.enforce_available_locales = true 21 | I18n.default_locale = :ja 22 | config.i18n.default_locale = :ja 23 | 24 | # https://coderwall.com/p/nnjrlq/multifile-uploads-with-carrierwave 25 | config.autoload_paths << Rails.root.join('app', 'field_types') 26 | 27 | config.active_job.queue_adapter = :delayed_job 28 | 29 | end 30 | end 31 | -------------------------------------------------------------------------------- /config/initializers/new_framework_defaults.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | # 3 | # This file contains migration options to ease your Rails 5.0 upgrade. 4 | # 5 | # Once upgraded flip defaults one by one to migrate to the new default. 6 | # 7 | # Read the Guide for Upgrading Ruby on Rails for more info on each option. 8 | 9 | Rails.application.config.action_controller.raise_on_unfiltered_parameters = true 10 | 11 | # Enable per-form CSRF tokens. Previous versions had false. 12 | Rails.application.config.action_controller.per_form_csrf_tokens = false 13 | 14 | # Enable origin-checking CSRF mitigation. Previous versions had false. 15 | Rails.application.config.action_controller.forgery_protection_origin_check = false 16 | 17 | # Make Ruby 2.4 preserve the timezone of the receiver when calling `to_time`. 18 | # Previous versions had false. 19 | ActiveSupport.to_time_preserves_timezone = false 20 | 21 | # Require `belongs_to` associations by default. Previous versions had false. 22 | Rails.application.config.active_record.belongs_to_required_by_default = false 23 | 24 | # Do not halt callback chains when a callback returns false. Previous versions had true. 25 | # ActiveSupport.halt_callback_chains_on_return_false = true 26 | -------------------------------------------------------------------------------- /app/views/top/help.html.erb: -------------------------------------------------------------------------------- 1 |
2 |

日本版Brigade CMS 3 | "Ha4go" リリースノート

4 |
5 | 2016.04.03 β1 Release
6 |
7 |

Ha4goの目指すもの

8 | このCMSの目指すものは、課題を深く知る市民とITに詳しいエンジニアが共通の基盤で情報交換し、課題を深化しシビックテックを活用しながら解決にまで進めてい 9 | くことができるオンラインの場所を作ることにあります。
10 |
11 | これにより
12 |

・地域課題の可視化により、市民の地域課題に対する理解と関心を広げる

13 |

・地域課題をオンラインで議論できる場所の提供

14 |

・課題解決に必要なヒト(市民やエンジニア・デザイナーなど)同士を繋ぐ

15 | など、地域とシビックテックを繋ぎ、地域課題を解決に導くひとつの仕組みになることを目指しています。
16 |
17 |
18 |

使い方(β1)

19 |
20 | ・ログイン
21 | Ha4goでは、広く一般の市民の方に参加いただくため、Facebookアカウントを利用します。
22 |
23 | ・プロフィール編集
24 | 自己紹介の他、課題解決のためのスキルを他の参加メンバーに明示するため、自分のもつスキルを登録することができます。
25 |
26 | ・課題の投稿
27 | ログイン後、「課題を投稿する」から投稿してください。
28 |
29 | ・メンバーへの参加
30 | すでに関心のある課題がある場合は各課題の詳細ページからメンバーに参加し、「フォローを書く」でコメントを登録することができます。
31 |
32 |
33 |

今後の予定

34 |
35 | まず基本的なマッチング機能を実装し、β1としてプロトタイプをリリースしました。
36 | 直近の予定として、2016年7月頃にデザインを刷新する予定です。
37 |
38 |
39 | -------------------------------------------------------------------------------- /db/migrate/20170507011046_create_delayed_jobs.rb: -------------------------------------------------------------------------------- 1 | class CreateDelayedJobs < ActiveRecord::Migration[4.2] 2 | def self.up 3 | create_table :delayed_jobs, force: true do |table| 4 | table.integer :priority, default: 0, null: false # Allows some jobs to jump to the front of the queue 5 | table.integer :attempts, default: 0, null: false # Provides for retries, but still fail eventually. 6 | table.text :handler, null: false # YAML-encoded string of the object that will do work 7 | table.text :last_error # reason for last failure (See Note below) 8 | table.datetime :run_at # When to run. Could be Time.zone.now for immediately, or sometime in the future. 9 | table.datetime :locked_at # Set when a client is working on this object 10 | table.datetime :failed_at # Set when all retries have failed (actually, by default, the record is deleted instead) 11 | table.string :locked_by # Who is working on this object (if locked) 12 | table.string :queue # The name of the queue this job is in 13 | table.timestamps null: true 14 | end 15 | 16 | add_index :delayed_jobs, [:priority, :run_at], name: "delayed_jobs_priority" 17 | end 18 | 19 | def self.down 20 | drop_table :delayed_jobs 21 | end 22 | end 23 | -------------------------------------------------------------------------------- /app/assets/stylesheets/matsu/jquery.mobile.menu.css: -------------------------------------------------------------------------------- 1 | #build-menu-page { 2 | left: 0; 3 | position: relative; 4 | } 5 | 6 | #build-menu { 7 | visibility: visible; 8 | z-index: 0; 9 | opacity: 1; 10 | -webkit-transform: none; 11 | display: none; 12 | width: 260px; 13 | padding: 0; 14 | position: static; 15 | z-index: 0; 16 | top: 0; 17 | height: 100%; 18 | overflow-y: auto; 19 | left: 0; 20 | float:right; 21 | } 22 | 23 | .build-menu-animating #build-menu-page { 24 | position: fixed; 25 | overflow: hidden; 26 | width: 100%; 27 | top: 0; 28 | bottom: 0; 29 | } 30 | 31 | .build-menu-animating.build-menu-close #build-menu-page, 32 | .build-menu-animating.build-menu-open #build-menu-page { 33 | -webkit-transition: -webkit-transform 250ms; 34 | } 35 | 36 | .build-menu-animating.build-menu-open #build-menu-page { 37 | -webkit-transform: translate3d(0, 0, 0); 38 | } 39 | 40 | .build-menu-animating #build-menu { display: block } 41 | 42 | .build-menu-open #build-menu { 43 | display: block; 44 | -webkit-transition-delay: 0ms, 0ms, 0ms; 45 | } 46 | 47 | .build-menu-open #build-menu, 48 | .build-menu-close #build-menu { 49 | -webkit-transition: -webkit-transform 250ms, opacity 250ms, visibility 0ms 250ms; 50 | } 51 | 52 | .li_sub{ 53 | padding: 15px 10px 14px 20px; 54 | border-bottom: 1px solid #fff; 55 | border-left: 1px solid #fff; 56 | background-color: #333; 57 | 58 | } 59 | 60 | .li_sub a{ 61 | color: #fff; 62 | font-weight: bold; 63 | } -------------------------------------------------------------------------------- /app/views/top/feed.rss.builder: -------------------------------------------------------------------------------- 1 | #encoding: UTF-8 2 | 3 | xml.instruct! :xml, version: '1.0' 4 | xml.rss version: '2.0' do 5 | xml.channel do 6 | xml.title 'Ha4go RSS Title' 7 | xml.description 'Code for Kanazawa.' 8 | protocol = 'http' 9 | protocol + 's' if ENV['USE_HTTPS'].to_i > 0 10 | url = "#{protocol}://#{ENV['APP_HOST']}" 11 | xml.link url 12 | xml.language 'ja' 13 | 14 | @projects.each do |article| 15 | xml.item do 16 | xml.title article.subject || '' 17 | xml.author article.user.name 18 | xml.pubDate article.created_at.to_s(:rfc822) 19 | xml.link "#{url}/projects/" + article.id.to_s 20 | xml.guid(article.id, isPermaLink: 'false') 21 | 22 | text = article.description 23 | # if you like, do something with your content text here e.g. insert image tags. 24 | # Optional. I'm doing this on my website. 25 | # if article.image.exists? 26 | # image_url = article.image.url(:large) 27 | # image_caption = article.image_caption 28 | # image_align = '' 29 | # image_tag = " 30 | #

" + image_caption + "

31 | # " 32 | # text = text.sub('{image}', image_tag) 33 | # end 34 | xml.description '

' + text + '

' 35 | end 36 | end 37 | end 38 | end 39 | -------------------------------------------------------------------------------- /app/models/user.rb: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | class User < ActiveRecord::Base 3 | # has_many :projects 4 | has_many :project_updates 5 | # belongs_to :project 6 | has_and_belongs_to_many :skills 7 | has_and_belongs_to_many :projects 8 | 9 | # OAuth 新規ユーザー作成 10 | # @param omniauthコールバックパラメータ 11 | def self.from_omniauth(auth) 12 | where(provider: auth.provider, uid: auth.uid).first_or_create do |user| 13 | user.provider = auth.provider 14 | user.uid = auth.uid 15 | user.name = auth.info.name 16 | user.image = auth.info.image 17 | user.save 18 | end 19 | end 20 | 21 | # 必要なスキルを更新 22 | # @param [Array] skill_names スキル名の配列 23 | # @return 増えたSKILLのID一覧 24 | def update_skill_ids_by_skill_names(skill_names) 25 | @before_skill_ids = skills.map(&:id) 26 | @after_skill_ids = [] 27 | 28 | if skill_names.present? 29 | skill_names.compact.uniq.reject(&:empty?).each do |skill_name| 30 | skill = Skill.find_by(name: skill_name) 31 | if skill.nil? 32 | skill = Skill.create(name: skill_name) 33 | end 34 | @after_skill_ids.push(skill.id) 35 | end 36 | end 37 | 38 | # 追加 39 | out = @after_skill_ids - @before_skill_ids 40 | out.each do |skill_id| 41 | skills << Skill.find(skill_id) 42 | end 43 | 44 | # 削除 45 | (@before_skill_ids - @after_skill_ids).each do |skill_id| 46 | skills.delete(skill_id) 47 | end 48 | 49 | return out 50 | end 51 | end 52 | -------------------------------------------------------------------------------- /app/views/projects/show.rss.builder: -------------------------------------------------------------------------------- 1 | #encoding: UTF-8 2 | 3 | xml.instruct! :xml, version: '1.0' 4 | xml.rss version: '2.0' do 5 | xml.channel do 6 | xml.title @project.subject 7 | xml.description @project.description 8 | protocol = 'http' 9 | protocol + 's' if ENV['USE_HTTPS'].to_i > 0 10 | url = "#{protocol}://#{ENV['APP_HOST']}/projects/#{@project.id}" 11 | xml.link url 12 | xml.language 'ja' 13 | 14 | @project.project_updates.each do |article| 15 | xml.item do 16 | xml.title article.created_at.to_s 17 | xml.author article.user.name 18 | xml.pubDate article.created_at.to_s(:rfc822) 19 | xml.link "#{url}#comment-" + article.id.to_s 20 | xml.guid(article.id, isPermaLink: 'false') 21 | 22 | text = article.description 23 | # if you like, do something with your content text here e.g. insert image tags. 24 | # Optional. I'm doing this on my website. 25 | # if article.image.exists? 26 | # image_url = article.image.url(:large) 27 | # image_caption = article.image_caption 28 | # image_align = '' 29 | # image_tag = " 30 | #

" + image_caption + "

31 | # " 32 | # text = text.sub('{image}', image_tag) 33 | # end 34 | xml.description '

' + text + '

' 35 | end 36 | end 37 | end 38 | end 39 | -------------------------------------------------------------------------------- /test/controllers/project_updates_controller_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class ProjectUpdatesControllerTest < ActionController::TestCase 4 | setup do 5 | @project_update = project_updates(:project_update_one) 6 | @controller.session[:user_id] = @project_update.user.id 7 | end 8 | 9 | test "should get new" do 10 | get :new 11 | assert_response :success 12 | end 13 | 14 | test "should create project_update" do 15 | assert_difference('ProjectUpdate.count') do 16 | post :create, params: { project_update: { description: @project_update.description, project_id: @project_update.project_id } } 17 | end 18 | 19 | assert_redirected_to project_path(@project_update.project) 20 | end 21 | 22 | test "should show project_update" do 23 | get :show, params: { id: @project_update } 24 | assert_response :success 25 | end 26 | 27 | test "should get edit" do 28 | get :edit, params: { id: @project_update } 29 | assert_response :success 30 | end 31 | 32 | test "should update project_update" do 33 | patch :update, params: { id: @project_update, project_update: { description: @project_update.description, project_id: @project_update.project_id } } 34 | assert_redirected_to project_path(@project_update.project) 35 | end 36 | 37 | test "should destroy project_update" do 38 | assert_no_difference('ProjectUpdate.count') do 39 | delete :destroy, params: { id: @project_update } 40 | end 41 | 42 | assert_redirected_to project_path(@project_update.project) 43 | end 44 | end 45 | -------------------------------------------------------------------------------- /config/secrets.yml: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Your secret key is used for verifying the integrity of signed cookies. 4 | # If you change this key, all old signed cookies will become invalid! 5 | 6 | # Make sure the secret is at least 30 characters and all random, 7 | # no regular words or you'll be exposed to dictionary attacks. 8 | # You can use `rails secret` to generate a secure secret key. 9 | 10 | # Make sure the secrets in this file are kept private 11 | # if you're sharing your code publicly. 12 | 13 | development: 14 | smtp_address: <%= ENV['SMTP_SERVER'] %> 15 | smtp_port: <%= ENV['SMTP_PORT'].to_i %> 16 | smtp_domain: <%= ENV['SMTP_DOMAIN'] %> 17 | smtp_user_name: <%= ENV['SMTP_USER'] %> 18 | smtp_password: <%= ENV['SMTP_PASSWORD'] %> 19 | secret_key_base: 302119ab88dd2e699bab093d48ebfe4fcae911d1ad7655ce025923453d4cd1dd2b548c31124e7e4f37a324074981d95e432fee2287856a0c4d1cbe406594c159 20 | 21 | test: 22 | secret_key_base: a7e322dbf527fb8f4a123f4a690edc50bad2f5ffaabce18aff4425ecdac61e30427df7ef792e7f3faa41a2593b622e8468893ebb094fbd54910e1d1936f47765 23 | 24 | # Do not keep production secrets in the repository, 25 | # instead read values from the environment. 26 | production: 27 | secret_key_base: <%= ENV["SECRET_KEY_BASE"] %> 28 | smtp_address: <%= ENV['SMTP_SERVER'] %> 29 | smtp_port: <%= ENV['SMTP_PORT'].to_i %> 30 | smtp_domain: <%= ENV['SMTP_DOMAIN'] %> 31 | smtp_user_name: <%= ENV['SMTP_USER'] %> 32 | smtp_password: <%= ENV['SMTP_PASSWORD'] %> 33 | ga_track_id: <%= ENV['GA_TRACK_ID'] %> 34 | -------------------------------------------------------------------------------- /app/assets/stylesheets/common.scss: -------------------------------------------------------------------------------- 1 | @for $i from 5 through 100 { 2 | .mt#{$i} { 3 | margin-top:#{$i}px; 4 | } 5 | 6 | .mb#{$i} { 7 | margin-bottom:#{$i}px; 8 | } 9 | 10 | .ml#{$i} { 11 | margin-left:#{$i}px; 12 | } 13 | 14 | .mr#{$i} { 15 | margin-right:#{$i}px; 16 | } 17 | } 18 | 19 | .navbar__custom { 20 | .navbar__menu-button { 21 | float: right; 22 | } 23 | } 24 | 25 | .menu__right { 26 | display: none; 27 | background-color: #333; 28 | list-style: none; 29 | position: fixed; 30 | top: 0px; 31 | } 32 | 33 | .spacer-navbar { 34 | height: 50px; 35 | } 36 | 37 | .column__top { 38 | .jumbotron { 39 | background-image: image-url("img_kanazawa.jpg"); 40 | background-repeat: no-repeat; 41 | background-size: cover; 42 | .container { 43 | height: 200px; 44 | } 45 | } 46 | 47 | .caption { 48 | padding: 20px; 49 | background-color: rgba(0,0,0,0.6); 50 | border-radius: 5px; 51 | display: box; 52 | display: -webkit-box; 53 | display: -moz-box; 54 | color: #fff; 55 | word-wrap: keep-all; 56 | } 57 | 58 | .caption__text { 59 | } 60 | } 61 | 62 | .panel-group { 63 | margin-top: 20px; 64 | 65 | .panel { 66 | margin-bottom: 20px; 67 | } 68 | 69 | .panel-heading { 70 | padding: 10px; 71 | font-size: 26px; 72 | } 73 | } 74 | 75 | .input_text { 76 | input { 77 | width: 100%; 78 | } 79 | 80 | textarea { 81 | width: 100%; 82 | } 83 | } -------------------------------------------------------------------------------- /app/controllers/application_controller.rb: -------------------------------------------------------------------------------- 1 | class ApplicationController < ActionController::Base 2 | # Prevent CSRF attacks by raising an exception. 3 | # For APIs, you may want to use :null_session instead. 4 | protect_from_forgery with: :exception 5 | 6 | before_action :authorized?, :check_use_https, :set_quick_link_counts, :save_current_url, :set_rss_url, :set_app_information 7 | 8 | helper_method :authorized? 9 | 10 | private 11 | 12 | def default_duration 13 | Time.now - 30.days 14 | end 15 | 16 | def authorized? 17 | @my_user = User.find_by(id: session[:user_id]) if session[:user_id] 18 | @my_user.present? 19 | end 20 | 21 | def check_use_https 22 | request.env['HTTP_X_FORWARDED_SSL'] = 'on' if ENV['USE_HTTPS'].to_i >= 1 23 | end 24 | 25 | def set_quick_link_counts 26 | @projects_recent_count = Project.recent.length 27 | @projects_hot_rank_count = Project.comment_ranking(default_duration).length 28 | @projects_all_count = Project.all.count 29 | if authorized? 30 | @projects_match = Project.match_skills(@my_user.skill_ids).length 31 | else 32 | @projects_match = @projects_all_count 33 | end 34 | end 35 | 36 | def save_current_url 37 | session[:current_url] = request.fullpath 38 | end 39 | 40 | def add_rss_urls(name, url) 41 | @rss_urls = Array(@rss_urls) << { name: name, url: url } 42 | @rss_urls.uniq! 43 | end 44 | 45 | def set_rss_url 46 | @rss_urls = [{ name: 'Ha4go Project List', url: '/feed.rss' }] 47 | end 48 | 49 | def set_app_information 50 | @app_infors = AppInformation.order(release: :desc).limit(10) 51 | end 52 | end 53 | -------------------------------------------------------------------------------- /test/controllers/projects_controller_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class ProjectsControllerTest < ActionController::TestCase 4 | setup do 5 | @project = projects(:project_one) 6 | @controller.session[:user_id] = @project.user.id 7 | end 8 | 9 | test "should get index" do 10 | get :index 11 | assert_response :success 12 | assert_not_nil assigns(:projects) 13 | end 14 | 15 | test "should get new" do 16 | get :new 17 | assert_response :success 18 | end 19 | 20 | test "should create project" do 21 | assert_difference('Project.count') do 22 | post :create, params: { project: { description: @project.description, development_url: @project.development_url, stage_id: @project.stage_id, subject: @project.subject, user_id: @project.user_id, user_url: @project.user_url }, skill_names: { skill_ids: [] }, new_skills: { new_skills: '' } } 23 | end 24 | 25 | assert_redirected_to project_path(assigns(:project)) 26 | end 27 | 28 | test "should show project" do 29 | get :show, params: { id: @project } 30 | assert_response :success 31 | end 32 | 33 | test "should get edit" do 34 | get :edit, params: { id: @project } 35 | assert_response :success 36 | end 37 | 38 | test "should update project" do 39 | patch :update, params: { id: @project, project: { description: @project.description, development_url: @project.development_url, stage_id: @project.stage_id, subject: @project.subject, user_id: @project.user_id, user_url: @project.user_url }, skill_names: { skill_ids: [] }, new_skills: { new_skills: '' } } 40 | assert_redirected_to project_path(assigns(:project)) 41 | end 42 | end 43 | -------------------------------------------------------------------------------- /app/uploaders/image_uploader.rb: -------------------------------------------------------------------------------- 1 | class ImageUploader < CarrierWave::Uploader::Base 2 | 3 | # Include RMagick or MiniMagick support: 4 | # include CarrierWave::RMagick 5 | # include CarrierWave::MiniMagick 6 | 7 | # Choose what kind of storage to use for this uploader: 8 | # storage :file 9 | 10 | # Override the directory where uploaded files will be stored. 11 | # This is a sensible default for uploaders that are meant to be mounted: 12 | def store_dir 13 | "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}" 14 | end 15 | 16 | # Provide a default URL as a default if there hasn't been a file uploaded: 17 | # def default_url 18 | # # For Rails 3.1+ asset pipeline compatibility: 19 | # # ActionController::Base.helpers.asset_path("fallback/" + [version_name, "default.png"].compact.join('_')) 20 | # 21 | # "/images/fallback/" + [version_name, "default.png"].compact.join('_') 22 | # end 23 | 24 | # Process files as they are uploaded: 25 | # process scale: [200, 300] 26 | # 27 | # def scale(width, height) 28 | # # do something 29 | # end 30 | 31 | # Create different versions of your uploaded files: 32 | # version :thumb do 33 | # process resize_to_fit: [50, 50] 34 | # end 35 | 36 | # Add a white list of extensions which are allowed to be uploaded. 37 | # For images you might use something like this: 38 | def extension_whitelist 39 | %w(jpg jpeg gif png) 40 | end 41 | 42 | # Override the filename of the uploaded files: 43 | # Avoid using model.id or version_name here, see uploader/store.rb for details. 44 | # def filename 45 | # "something.jpg" if original_filename 46 | # end 47 | 48 | end 49 | -------------------------------------------------------------------------------- /app/uploaders/comment_image_uploader.rb: -------------------------------------------------------------------------------- 1 | class CommentImageUploader < CarrierWave::Uploader::Base 2 | 3 | # Include RMagick or MiniMagick support: 4 | # include CarrierWave::RMagick 5 | # include CarrierWave::MiniMagick 6 | 7 | # Choose what kind of storage to use for this uploader: 8 | # storage :fog 9 | 10 | # Override the directory where uploaded files will be stored. 11 | # This is a sensible default for uploaders that are meant to be mounted: 12 | def store_dir 13 | "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}" 14 | end 15 | 16 | # Provide a default URL as a default if there hasn't been a file uploaded: 17 | # def default_url 18 | # # For Rails 3.1+ asset pipeline compatibility: 19 | # # ActionController::Base.helpers.asset_path("fallback/" + [version_name, "default.png"].compact.join('_')) 20 | # 21 | # "/images/fallback/" + [version_name, "default.png"].compact.join('_') 22 | # end 23 | 24 | # Process files as they are uploaded: 25 | # process scale: [200, 300] 26 | # 27 | # def scale(width, height) 28 | # # do something 29 | # end 30 | 31 | # Create different versions of your uploaded files: 32 | # version :thumb do 33 | # process resize_to_fit: [50, 50] 34 | # end 35 | 36 | # Add a white list of extensions which are allowed to be uploaded. 37 | # For images you might use something like this: 38 | def extension_whitelist 39 | %w(jpg jpeg gif png) 40 | end 41 | 42 | # Override the filename of the uploaded files: 43 | # Avoid using model.id or version_name here, see uploader/store.rb for details. 44 | # def filename 45 | # "something.jpg" if original_filename 46 | # end 47 | 48 | end 49 | -------------------------------------------------------------------------------- /public/500.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | We're sorry, but something went wrong (500) 5 | 6 | 55 | 56 | 57 | 58 | 59 |
60 |
61 |

We're sorry, but something went wrong.

62 |
63 |

If you are the application owner check the logs for more information.

64 |
65 | 66 | 67 | -------------------------------------------------------------------------------- /public/422.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | The change you wanted was rejected (422) 5 | 6 | 55 | 56 | 57 | 58 | 59 |
60 |
61 |

The change you wanted was rejected.

62 |

Maybe you tried to change something you didn't have access to.

63 |
64 |

If you are the application owner check the logs for more information.

65 |
66 | 67 | 68 | -------------------------------------------------------------------------------- /app/helpers/application_helper.rb: -------------------------------------------------------------------------------- 1 | module ApplicationHelper 2 | def full_title(page_title) 3 | base_title = "Ha4go" 4 | page_title.blank? ? base_title : "#{page_title} | #{base_title}" 5 | end 6 | 7 | def br(text) 8 | return text if text.nil? 9 | text = h text 10 | text.gsub(/\r\n|\r|\n/, '
').html_safe 11 | end 12 | 13 | require "uri" 14 | 15 | def description_text(text, length = 65_536) 16 | out = text.to_s 17 | URI.extract(out, %w(http https)).uniq.each do |url| 18 | sub_text = "" 19 | sub_text << "" << url << "" 20 | 21 | out = out.gsub(url, sub_text) 22 | end 23 | out.gsub(/\r\n|\r|\n/, '
')[0..(length - 1)].html_safe 24 | end 25 | 26 | def ago_with_title(target_datetime, link) 27 | if link.nil? 28 | %(#{time_ago_in_words(target_datetime)}).html_safe 29 | else 30 | %(#{link_to(time_ago_in_words(target_datetime), link)}).html_safe 31 | end 32 | end 33 | 34 | def updated_at_with_link(record_with_updated_at, link) 35 | ago_with_title(record_with_updated_at.updated_at, link) 36 | end 37 | 38 | alias updated_at_ago updated_at_with_link 39 | 40 | def created_at_ago(record_with_created_at, link = nil) 41 | ago_with_title(record_with_created_at.created_at, link) 42 | end 43 | 44 | def user_with_face(user_record) 45 | link_to( 46 | image_tag(user_record.image, alt: user_record.name, title: user_record.name) + user_record.name, 47 | user_path(id: user_record.id) 48 | ) 49 | end 50 | 51 | def project_path_with_comment(project_updates_record) 52 | project_path( 53 | id: project_updates_record.project.id, 54 | anchor: "comment-#{project_updates_record.id}" 55 | ) 56 | end 57 | end 58 | -------------------------------------------------------------------------------- /public/404.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | The page you were looking for doesn't exist (404) 5 | 6 | 55 | 56 | 57 | 58 | 59 |
60 |
61 |

The page you were looking for doesn't exist.

62 |

You may have mistyped the address or the page may have moved.

63 |
64 |

If you are the application owner check the logs for more information.

65 |
66 | 67 | 68 | -------------------------------------------------------------------------------- /app/controllers/users_controller.rb: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | 3 | class UsersController < ApplicationController 4 | before_action :set_user, only: [:show, :edit, :update] 5 | 6 | # GET /users 7 | # GET /users.json 8 | def index 9 | @skills = Skill.all 10 | skills = Skill.all.map { |skill| [skill.name, skill.id] } 11 | @options = skills.unshift(['指定なし', nil]) 12 | 13 | if params[:skill_id].present? 14 | @users = User.joins(:skills).where(skills: { id: params[:skill_id] }) 15 | else 16 | @users = User.all 17 | end 18 | end 19 | 20 | # GET /users/1 21 | # GET /users/1.json 22 | def show 23 | end 24 | 25 | # GET /users/1/edit 26 | def edit 27 | @from = params['from'] 28 | end 29 | 30 | # PATCH/PUT /users/1 31 | def update 32 | if @user.update(user_params) 33 | skills = Array(params.dig(:skill_names, :skill_ids)) + params.dig(:new_skills, :new_skills).split(' ') 34 | @user.update_skill_ids_by_skill_names(skills) if skills.size > 0 35 | if params[:from].to_s == 'dashboard' 36 | redirect_to '/dashboard', notice: 'プロフィールを更新しました。' 37 | else 38 | redirect_to @user, notice: 'プロフィールを更新しました。' 39 | end 40 | else 41 | render :edit 42 | end 43 | end 44 | 45 | private 46 | 47 | # Use callbacks to share common setup or constraints between actions. 48 | def set_user 49 | @user = User.find(params[:id]) 50 | @skills = Skill.all 51 | @my_skills = @user.skills.all.map { |k| k[:name] } 52 | @my_comments = ProjectUpdate.where(user_id: @user.id, freezing: [0, nil]).order(created_at: :desc).limit(10) 53 | end 54 | 55 | # Never trust parameters from the scary internet, only allow the white list through. 56 | def user_params 57 | params.require(:user).permit(:name, :email, :password, :description, :facebook_user_id, :receive_all) 58 | end 59 | end 60 | -------------------------------------------------------------------------------- /config/environments/test.rb: -------------------------------------------------------------------------------- 1 | Rails.application.configure do 2 | # Settings specified here will take precedence over those in config/application.rb. 3 | 4 | # The test environment is used exclusively to run your application's 5 | # test suite. You never need to work with it otherwise. Remember that 6 | # your test database is "scratch space" for the test suite and is wiped 7 | # and recreated between test runs. Don't rely on the data there! 8 | config.cache_classes = true 9 | 10 | # Do not eager load code on boot. This avoids loading your whole application 11 | # just for the purpose of running a single test. If you are using a tool that 12 | # preloads Rails for running tests, you may have to set it to true. 13 | config.eager_load = false 14 | 15 | # Configure public file server for tests with Cache-Control for performance. 16 | config.public_file_server.enabled = true 17 | config.public_file_server.headers = { 18 | 'Cache-Control' => 'public, max-age=3600' 19 | } 20 | 21 | # Show full error reports and disable caching. 22 | config.consider_all_requests_local = true 23 | config.action_controller.perform_caching = false 24 | 25 | # Raise exceptions instead of rendering exception templates. 26 | config.action_dispatch.show_exceptions = false 27 | 28 | # Disable request forgery protection in test environment. 29 | config.action_controller.allow_forgery_protection = false 30 | config.action_mailer.perform_caching = false 31 | 32 | # Tell Action Mailer not to deliver emails to the real world. 33 | # The :test delivery method accumulates sent emails in the 34 | # ActionMailer::Base.deliveries array. 35 | config.action_mailer.delivery_method = :test 36 | 37 | # Randomize the order test cases are executed. 38 | config.active_support.test_order = :random 39 | 40 | # Print deprecation notices to the stderr. 41 | config.active_support.deprecation = :stderr 42 | 43 | config.action_mailer.default_url_options = { host: 'localhost' } 44 | 45 | # Raises error for missing translations 46 | # config.action_view.raise_on_missing_translations = true 47 | end 48 | -------------------------------------------------------------------------------- /config/puma.rb: -------------------------------------------------------------------------------- 1 | # Puma can serve each request in a thread from an internal thread pool. 2 | # The `threads` method setting takes two numbers a minimum and maximum. 3 | # Any libraries that use thread pools should be configured to match 4 | # the maximum value specified for Puma. Default is set to 5 threads for minimum 5 | # and maximum, this matches the default thread size of Active Record. 6 | # 7 | threads_count = ENV.fetch("RAILS_MAX_THREADS") { 5 }.to_i 8 | threads threads_count, threads_count 9 | 10 | # Specifies the `port` that Puma will listen on to receive requests, default is 3000. 11 | # 12 | port ENV.fetch("PORT") { 3000 } 13 | 14 | # Specifies the `environment` that Puma will run in. 15 | # 16 | environment ENV.fetch("RAILS_ENV") { "development" } 17 | 18 | # Specifies the number of `workers` to boot in clustered mode. 19 | # Workers are forked webserver processes. If using threads and workers together 20 | # the concurrency of the application would be max `threads` * `workers`. 21 | # Workers do not work on JRuby or Windows (both of which do not support 22 | # processes). 23 | # 24 | # workers ENV.fetch("WEB_CONCURRENCY") { 2 } 25 | 26 | # Use the `preload_app!` method when specifying a `workers` number. 27 | # This directive tells Puma to first boot the application and load code 28 | # before forking the application. This takes advantage of Copy On Write 29 | # process behavior so workers use less memory. If you use this option 30 | # you need to make sure to reconnect any threads in the `on_worker_boot` 31 | # block. 32 | # 33 | # preload_app! 34 | 35 | # The code in the `on_worker_boot` will be called if you are using 36 | # clustered mode by specifying a number of `workers`. After each worker 37 | # process is booted this block will be run, if you are using `preload_app!` 38 | # option you will want to use this block to reconnect to any threads 39 | # or connections that may have been created at application boot, Ruby 40 | # cannot share connections between processes. 41 | # 42 | # on_worker_boot do 43 | # ActiveRecord::Base.establish_connection if defined?(ActiveRecord) 44 | # end 45 | 46 | # Allow puma to be restarted by `rails restart` command. 47 | plugin :tmp_restart 48 | -------------------------------------------------------------------------------- /app/assets/stylesheets/matsu/reset.scss: -------------------------------------------------------------------------------- 1 | @charset "UTF-8"; 2 | 3 | /* CSS Document */ 4 | 5 | /* 6 | html5doctor.com Reset Stylesheet 7 | v1.4 8 | 2009-07-27 9 | Author: Richard Clark - http://richclarkdesign.com 10 | */ 11 | 12 | html, body, div, span, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, abbr, address, cite, code, del, dfn, em, img, ins, kbd, q, samp, small, strong, sub, sup, var, b, i, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td, article, aside, dialog, figure, footer, header, hgroup, menu, nav, section, time, mark, audio, video { 13 | margin: 0; 14 | padding: 0; 15 | border: 0; 16 | outline: 0; 17 | font-size: 100%; 18 | vertical-align: baseline; 19 | background: transparent; 20 | } 21 | 22 | body { 23 | line-height: 1; 24 | } 25 | 26 | article, aside, dialog, figure, footer, header, hgroup, nav, section { 27 | display: block; 28 | } 29 | 30 | nav ul { 31 | list-style: none; 32 | } 33 | 34 | blockquote, q { 35 | quotes: none; 36 | } 37 | 38 | blockquote { 39 | &:before, &:after { 40 | content: ''; 41 | content: none; 42 | } 43 | } 44 | 45 | q { 46 | &:before, &:after { 47 | content: ''; 48 | content: none; 49 | } 50 | } 51 | 52 | a { 53 | margin: 0; 54 | padding: 0; 55 | border: 0; 56 | font-size: 100%; 57 | vertical-align: baseline; 58 | background: transparent; 59 | } 60 | 61 | ins { 62 | background-color: #ff9; 63 | color: #000; 64 | text-decoration: none; 65 | } 66 | 67 | mark { 68 | background-color: #ff9; 69 | color: #000; 70 | font-style: italic; 71 | font-weight: bold; 72 | } 73 | 74 | del { 75 | text-decoration: line-through; 76 | } 77 | 78 | abbr[title], dfn[title] { 79 | border-bottom: 1px dotted #000; 80 | cursor: help; 81 | } 82 | 83 | table { 84 | border-collapse: collapse; 85 | border-spacing: 0; 86 | } 87 | 88 | hr { 89 | display: block; 90 | height: 1px; 91 | border: 0; 92 | border-top: 1px solid #cccccc; 93 | margin: 1em 0; 94 | padding: 0; 95 | } 96 | 97 | input, select { 98 | vertical-align: middle; 99 | } 100 | -------------------------------------------------------------------------------- /app/views/users/_form.html.erb: -------------------------------------------------------------------------------- 1 | <%= form_for(@user) do |f| %> 2 | <%= hidden_field_tag :from, @from.to_s %> 3 | 4 | <% if @user.errors.any? %> 5 |
6 |

<%= pluralize(@user.errors.count, "error") %>入力に誤りがあります

7 | 8 | 13 |
14 | <% end %> 15 | 16 |
17 |
18 |
19 | <%= t('dic.name')%> 20 |
21 |
22 | <%= f.text_field :name %> 23 |
24 |
25 |
26 |
27 | <%= t('dic.self_intro')%> 28 |
29 |
30 | <%= f.text_area :description, class: 'form-control', rows: 5 %> 31 |
32 |
33 |
34 |
35 | <%= t('dic.email')%><%= t('dic.not_public')%> 36 |
37 |
38 | <%= f.text_field :email, :class => 'form-control' %> 39 |
40 |
41 |
42 |
43 | <%= t('dic.receive_all') %> 44 |
45 |
46 | <%= f.label(:receive_all) do %> 47 | <%= f.check_box(:receive_all, checked: !@user.receive_all.nil? && @user.receive_all) %> 48 | <% end %> 49 |
50 |
51 |
52 |
53 | <%= t('dic.able_to')%> 54 |
55 |
56 | <%= collection_check_boxes(:skill_names, :skill_ids, Skill.all, :name, :name) do |b| %> 57 | <%= b.label { b.check_box(checked: @my_skills.include?(b.text)) + b.text } %> 58 | <% end %> 59 |
60 |
61 |
62 |
63 | <%= t '.new_skill'%> 64 |
65 |
66 | <%= text_field :new_skills, :new_skills %> 67 |
68 |
69 |
70 | 73 | <% end %> 74 | -------------------------------------------------------------------------------- /app/assets/javascripts/matsu/html5shiv.js: -------------------------------------------------------------------------------- 1 | /* 2 | HTML5 Shiv v3.6.2pre | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed 3 | */ 4 | (function(l,f){function m(){var a=e.elements;return"string"==typeof a?a.split(" "):a}function i(a){var b=n[a[o]];b||(b={},h++,a[o]=h,n[h]=b);return b}function p(a,b,c){b||(b=f);if(g)return b.createElement(a);c||(c=i(b));b=c.cache[a]?c.cache[a].cloneNode():r.test(a)?(c.cache[a]=c.createElem(a)).cloneNode():c.createElem(a);return b.canHaveChildren&&!s.test(a)?c.frag.appendChild(b):b}function t(a,b){if(!b.cache)b.cache={},b.createElem=a.createElement,b.createFrag=a.createDocumentFragment,b.frag=b.createFrag(); 5 | a.createElement=function(c){return!e.shivMethods?b.createElem(c):p(c,a,b)};a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+m().join().replace(/\w+/g,function(a){b.createElem(a);b.frag.createElement(a);return'c("'+a+'")'})+");return n}")(e,b.frag)}function q(a){a||(a=f);var b=i(a);if(e.shivCSS&&!j&&!b.hasCSS){var c,d=a;c=d.createElement("p");d=d.getElementsByTagName("head")[0]||d.documentElement;c.innerHTML="x"; 6 | c=d.insertBefore(c.lastChild,d.firstChild);b.hasCSS=!!c}g||t(a,b);return a}var k=l.html5||{},s=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,r=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,j,o="_html5shiv",h=0,n={},g;(function(){try{var a=f.createElement("a");a.innerHTML="";j="hidden"in a;var b;if(!(b=1==a.childNodes.length)){f.createElement("a");var c=f.createDocumentFragment();b="undefined"==typeof c.cloneNode|| 7 | "undefined"==typeof c.createDocumentFragment||"undefined"==typeof c.createElement}g=b}catch(d){g=j=!0}})();var e={elements:k.elements||"abbr article aside audio bdi canvas data datalist details figcaption figure footer header hgroup mark meter nav output progress section summary time video",version:"3.6.2pre",shivCSS:!1!==k.shivCSS,supportsUnknownElements:g,shivMethods:!1!==k.shivMethods,type:"default",shivDocument:q,createElement:p,createDocumentFragment:function(a,b){a||(a=f);if(g)return a.createDocumentFragment(); 8 | for(var b=b||i(a),c=b.frag.cloneNode(),d=0,e=m(),h=e.length;d 'public, max-age=172800' 22 | } 23 | else 24 | config.action_controller.perform_caching = false 25 | 26 | config.cache_store = :null_store 27 | end 28 | 29 | # Don't care if the mailer can't send. 30 | config.action_mailer.raise_delivery_errors = true 31 | config.action_mailer.delivery_method = ENV['DELIVERY_METHOD'] ? ENV['DELIVERY_METHOD'].to_sym : :letter_opener_web 32 | config.action_mailer.smtp_settings = { 33 | address: Rails.application.secrets.smtp_address, 34 | port: Rails.application.secrets.smtp_port, 35 | domain: Rails.application.secrets.smtp_domain, 36 | user_name: Rails.application.secrets.smtp_user_name, 37 | password: Rails.application.secrets.smtp_password, 38 | authentication: 'plain', 39 | enable_starttls_auto: true 40 | } 41 | config.action_mailer.default_url_options = { 42 | host: ENV['APP_HOST'] || 'localhost:3000' 43 | } 44 | 45 | config.action_mailer.perform_caching = false 46 | # Print deprecation notices to the Rails logger. 47 | config.active_support.deprecation = :log 48 | 49 | # Raise an error on page load if there are pending migrations. 50 | config.active_record.migration_error = :page_load 51 | 52 | # Debug mode disables concatenation and preprocessing of assets. 53 | # This option may cause significant delays in view rendering with a large 54 | # number of complex assets. 55 | config.assets.debug = true 56 | 57 | # Suppress logger output for asset requests. 58 | config.assets.quiet = true 59 | 60 | # Raises error for missing translations 61 | # config.action_view.raise_on_missing_translations = true 62 | 63 | # Use an evented file watcher to asynchronously detect changes in source code, 64 | # routes, locales, etc. This feature depends on the listen gem. 65 | # config.file_watcher = ActiveSupport::EventedFileUpdateChecker 66 | end 67 | -------------------------------------------------------------------------------- /app/controllers/project_updates_controller.rb: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | class ProjectUpdatesController < ApplicationController 3 | include SnsPublisher 4 | before_action :set_project_update, only: [:show, :edit, :update, :destroy] 5 | 6 | # GET /project_updates/new 7 | def new 8 | @project_update = ProjectUpdate.new 9 | end 10 | 11 | # GET /project_updates/1/edit 12 | def edit 13 | end 14 | 15 | # POST /project_updates 16 | def create 17 | @project_update = ProjectUpdate.new(project_update_params) 18 | @project_update.user_id = @my_user.id 19 | 20 | if @project_update.save 21 | @project_update.project.send_mail_addresses.each do |m| 22 | ProjectMailer.tell_update(m, @project_update).deliver_later unless m == '' 23 | end 24 | 25 | @project_update.project.update!( 26 | last_commented_at: @project_update.created_at 27 | ) 28 | project_publish_to_sns_page( 29 | "#{@my_user.name} さんが課題 #{@project_update.project.subject} にフォローを投稿しました。", 30 | @project_update.project, 31 | @my_user 32 | ) 33 | 34 | redirect_to project_path(id: params[:project_update][:project_id]), notice: 'フォローを投稿しました。' 35 | else 36 | render :new 37 | end 38 | end 39 | 40 | # PATCH/PUT /project_updates/1 41 | def update 42 | unless @project_update.user_id == @my_user.id || @project_update.project.user_id == @my_user.id 43 | redirect_to project_path(id: params[:project_update][:project_id]), notice: 'フォローを修正できませんでした' 44 | end 45 | 46 | if @project_update.update(project_update_params) 47 | history = ProjectUpdateHistory.new( 48 | user_id: @my_user.id, 49 | project_update_id: @project_update.id 50 | ) 51 | history.save 52 | redirect_to project_path(id: params[:project_update][:project_id]), notice: 'フォローを修正しました。' 53 | else 54 | render :edit 55 | end 56 | end 57 | 58 | # DELETE /project_updates/1 59 | def destroy 60 | @project_update.description = "( #{@my_user.name} さんが削除しました )" 61 | @project_update.comment_image = nil 62 | @project_update.freezing = true 63 | if @project_update.save 64 | history = ProjectUpdateHistory.new( 65 | user_id: @my_user.id, 66 | project_update_id: @project_update.id 67 | ) 68 | history.save 69 | end 70 | redirect_to project_path(id: @project_update.project_id), notice: 'フォローを削除しました。' 71 | end 72 | 73 | private 74 | 75 | # Use callbacks to share common setup or constraints between actions. 76 | def set_project_update 77 | @project_update = ProjectUpdate.find(params[:id]) 78 | end 79 | 80 | # Never trust parameters from the scary internet, only allow the white list through. 81 | def project_update_params 82 | params.require(:project_update).permit(:project_id, :description, :comment_image) 83 | end 84 | end 85 | -------------------------------------------------------------------------------- /Rakefile.deploy: -------------------------------------------------------------------------------- 1 | require 'dotenv' 2 | 3 | Dotenv.load 4 | 5 | SUDO = ENV['SUDO'] || '' 6 | NOCACHE = ENV['NOCACHE'] || '' 7 | 8 | DOCKER = [SUDO, 'docker'].join(' ') 9 | APP_NAME = 'ha4go'.freeze 10 | 11 | ROLE_FRONT = 'front' 12 | ROLE_JOB = 'job' 13 | ROLE_DB = 'db' 14 | ROLE_BASE = 'base' 15 | 16 | NAMES = { 17 | ROLE_BASE => "#{APP_NAME}-#{ROLE_BASE}", 18 | ROLE_FRONT => "#{APP_NAME}-#{ROLE_FRONT}", 19 | ROLE_JOB => "#{APP_NAME}-#{ROLE_FRONT}", # FRONTと同じ 20 | ROLE_DB => "#{APP_NAME}-#{ROLE_DB}" 21 | }.freeze 22 | TAGS = { 23 | ROLE_BASE => '1.0', 24 | ROLE_FRONT => '1.0', 25 | ROLE_JOB => '1.0', 26 | ROLE_DB => '1.0' 27 | }.freeze 28 | FILES = { 29 | ROLE_BASE => "Dockerfile.#{ROLE_BASE}", 30 | ROLE_FRONT => "Dockerfile.#{ROLE_FRONT}", 31 | ROLE_JOB => "Dockerfile.#{ROLE_FRONT}", # FRONTと同じ 32 | ROLE_DB => "Dockerfile.#{ROLE_DB}" 33 | } 34 | RELEASE_TAG = "release".freeze 35 | 36 | DOCKER_OPTIONS = { 37 | 'PRODUCT' => { 38 | ROLE_BASE => '', 39 | ROLE_FRONT => "-d -p 3000:3000 --env-file=.env --log-opt max-size=100m --log-opt max-file=3 -v `pwd`/public/uploads:/myapp/public/uploads", 40 | ROLE_JOB => '-d --env-file=.env', 41 | ROLE_DB => "-d -v `pwd`/mysql:/var/lib/mysql -p 3306:3306" 42 | }, 43 | 'DEBUG' => { 44 | ROLE_FRONT => '-d -p 3000:3000 --env-file=.env', 45 | ROLE_JOB => '', 46 | ROLE_DB => "-d -v `pwd`/mysql:/var/lib/mysql -p 3306:3306" 47 | } 48 | } 49 | 50 | DOCKER_COMMAND = { 51 | 'PRODUCT' => { 52 | ROLE_JOB => 'bundle exec rake jobs:work' 53 | }, 54 | 'DEBUG' => { 55 | ROLE_JOB => 'bundle exec rake jobs:work' 56 | } 57 | } 58 | 59 | class Cmd 60 | def self.gen(values) 61 | values.join(' ') 62 | end 63 | end 64 | 65 | desc "build[base/db/front/job]" 66 | task :build, [:role] do |_t, a| 67 | r = a[:role] 68 | sh Cmd.gen( 69 | [ 70 | DOCKER, 71 | 'build', 72 | NOCACHE, 73 | "-t #{NAMES[r]}:#{TAGS[r]}", 74 | "-f #{FILES[r]}", 75 | './' 76 | ] 77 | ) 78 | end 79 | 80 | desc 'run[,,<`docker-machine ip default`>]' 81 | task :run, [:role, :local, :docker_ip] do |_t, a| 82 | r = a[:role] 83 | e = a[:local] || 'DEBUG' 84 | sh Cmd.gen([ 85 | DOCKER, 86 | "run --name ha4go-#{r.downcase}", 87 | "#{DOCKER_OPTIONS[e][r]}", 88 | "#{NAMES[r]}:#{TAGS[r]}", 89 | "#{DOCKER_COMMAND[e][r]}" 90 | ]) 91 | end 92 | 93 | desc 'console[,,<`docker-machine ip default`>]' 94 | task :console, [:role, :local, :docker_ip] do |_t, a| 95 | r = a[:role] 96 | e = a[:local] || 'DEBUG' 97 | sh Cmd.gen([ 98 | DOCKER, 99 | "exec -it ha4go-#{r.downcase}", 100 | 'bash' 101 | ]) 102 | end -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | source 'https://rubygems.org' 3 | 4 | ruby '~> 2.6.0' 5 | 6 | # Bundle edge Rails instead: gem 'rails', github: 'rails/rails' 7 | gem 'rails', '~> 5.2.0' 8 | # Use sqlite3 as the database for Active Record 9 | # gem 'sqlite3', groups: %w(test development), require: false 10 | # gem 'pg', groups: %w(production), require: false 11 | gem 'mysql2' 12 | # Use SCSS for stylesheets 13 | gem 'sass-rails', '~> 5.0' 14 | # Use Uglifier as compressor for JavaScript assets 15 | gem 'uglifier', '>= 1.3.0' 16 | # Use CoffeeScript for .coffee assets and views 17 | gem 'coffee-rails', '~> 4.2' 18 | # See https://github.com/rails/execjs#readme for more supported runtimes 19 | # gem 'therubyracer', platforms: :ruby 20 | gem 'bootstrap-sass', '~> 3.4.1' 21 | 22 | # Use jquery as the JavaScript library 23 | gem 'jquery-rails' 24 | # Turbolinks makes following links in your web application faster. Read more: https://github.com/rails/turbolinks 25 | # gem 'turbolinks' 26 | # Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder 27 | gem 'jbuilder', '~> 2.5' 28 | 29 | gem 'puma' 30 | 31 | gem 'omniauth-facebook' 32 | 33 | gem 'meta-tags' 34 | 35 | install_if -> { ENV['EMAIL_SERVICE'] == 'sendgrid' } do 36 | gem 'sendgrid-ruby' 37 | end 38 | 39 | group :development do 40 | # Access an IRB console on exception pages or by using <%= console %> anywhere in the code 41 | gem 'web-console', '>= 3.3.0' 42 | gem 'listen', '~> 3.0.5' 43 | end 44 | 45 | group :development, :test do 46 | gem 'pry-rails' 47 | gem 'pry-doc' 48 | gem 'pry-byebug' 49 | gem 'pry-stack_explorer' 50 | 51 | gem 'rubocop', require: false 52 | 53 | # Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring 54 | gem 'spring' 55 | gem 'dotenv-rails' 56 | 57 | gem 'rails-erd' 58 | end 59 | 60 | group :development do 61 | gem 'letter_opener' 62 | gem 'letter_opener_web' 63 | end 64 | 65 | gem 'rails-controller-testing', group: :test 66 | 67 | group :production do 68 | # gem 'pg' 69 | end 70 | 71 | # Herokuログ出力用 72 | gem 'rails_12factor', group: :production 73 | 74 | #gem 'compass', :git => 'git://github.com/chriseppstein/compass.git' 75 | gem 'compass' 76 | gem 'compass-rails', :git => 'git://github.com/Compass/compass-rails.git' 77 | 78 | gem 'google-analytics-rails' 79 | 80 | gem 'koala', '~> 2.2' 81 | 82 | # for Image upload 83 | # gem 'carrierwave', github: 'carrierwaveuploader/carrierwave' 84 | gem 'carrierwave', '~> 1.0' 85 | gem 'rmagick', '~> 2.0' 86 | 87 | install_if -> { ENV['STORAGE_SERVICE'] == 'amazon-s3' } do 88 | gem 'fog-aws' 89 | end 90 | 91 | # backgroud job 92 | gem 'delayed_job_active_record' 93 | 94 | # Windows does not include zoneinfo files, so bundle the tzinfo-data gem 95 | gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby] 96 | 97 | gem 'kaminari' 98 | 99 | gem 'rubocop-performance' 100 | -------------------------------------------------------------------------------- /db/seeds/users.yml.sample: -------------------------------------------------------------------------------- 1 | --- 2 | # ha4go は Facebook ログインを利用しているため、 uid はその Facebook が払い出したIDを本来用いないといけませんが、 3 | # ここではダミーの値を用いてます。この値を使っても Facebook と連携はとれません。 4 | - provider: facebook 5 | uid: '108042236335534' 6 | email: user1@ha4go.net 7 | info: 8 | name: 寺分 五郎太 9 | image: http://placehold.jp/100x100.png?text={ダミー画像} 10 | extra: 11 | raw_info: 12 | name: 寺分 五郎太 13 | id: '108042236335534' 14 | birthday: 06/04/1953 15 | - provider: facebook 16 | uid: '129490564185647' 17 | email: user2@ha4go.net 18 | info: 19 | name: 紺田 かをる 20 | image: http://placehold.jp/100x100.png?text={ダミー画像} 21 | extra: 22 | raw_info: 23 | name: 紺田 かをる 24 | id: '129490564185647' 25 | birthday: 10/13/2000 26 | - provider: facebook 27 | uid: '109065222899468' 28 | email: user3@ha4go.net 29 | info: 30 | name: 仲上 梅安 31 | image: http://placehold.jp/100x100.png?text={ダミー画像} 32 | extra: 33 | raw_info: 34 | name: 仲上 梅安 35 | id: '109065222899468' 36 | birthday: 07/20/1999 37 | - provider: facebook 38 | uid: '107694676370654' 39 | email: user4@ha4go.net 40 | info: 41 | name: 鶴間 親元 42 | image: http://placehold.jp/100x100.png?text={ダミー画像} 43 | extra: 44 | raw_info: 45 | name: 鶴間 親元 46 | id: '107694676370654' 47 | birthday: 11/07/1964 48 | - provider: facebook 49 | uid: '113194775817938' 50 | email: user5@ha4go.net 51 | info: 52 | name: 常本 友紀 53 | image: http://placehold.jp/100x100.png?text={ダミー画像} 54 | extra: 55 | raw_info: 56 | name: 常本 友紀 57 | id: '113194775817938' 58 | birthday: 11/03/1962 59 | - provider: facebook 60 | uid: '112430925894441' 61 | email: user6@ha4go.net 62 | info: 63 | name: 石間 精二 64 | image: http://placehold.jp/100x100.png?text={ダミー画像} 65 | extra: 66 | raw_info: 67 | name: 石間 精二 68 | id: '112430925894441' 69 | birthday: 02/09/1987 70 | - provider: facebook 71 | uid: '125899821212190' 72 | email: user7@ha4go.net 73 | info: 74 | name: 仁志 浩寿 75 | image: http://placehold.jp/100x100.png?text={ダミー画像} 76 | extra: 77 | raw_info: 78 | name: 仁志 浩寿 79 | id: '125899821212190' 80 | birthday: 03/19/1956 81 | - provider: facebook 82 | uid: '113020549168769' 83 | email: user8@ha4go.net 84 | info: 85 | name: 光明 沙都子 86 | image: http://placehold.jp/100x100.png?text={ダミー画像} 87 | extra: 88 | raw_info: 89 | name: 光明 沙都子 90 | id: '113020549168769' 91 | birthday: 04/02/1992 92 | - provider: facebook 93 | uid: '113219372482380' 94 | email: user9@ha4go.net 95 | info: 96 | name: 大仁 たけお 97 | image: http://placehold.jp/100x100.png?text={ダミー画像} 98 | extra: 99 | raw_info: !ruby/hash:OmniAuth::AuthHash 100 | name: 大仁 たけお 101 | id: '113219372482380' 102 | birthday: 12/17/1987 103 | - provider: facebook 104 | uid: '120178591785317' 105 | email: user10@ha4go.net 106 | info: 107 | name: 伊野部 鶴代 108 | image: http://placehold.jp/100x100.png?text={ダミー画像} 109 | extra: 110 | raw_info: 111 | name: 伊野部 鶴代 112 | id: '120178591785317' 113 | birthday: 07/04/2000 114 | -------------------------------------------------------------------------------- /app/models/project.rb: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | class Project < ActiveRecord::Base 3 | attribute :images, ArrayType.new 4 | mount_uploaders :images, ImageUploader 5 | serialize :images, JSON 6 | validates :subject, presence: true 7 | has_many :project_updates 8 | belongs_to :user 9 | has_and_belongs_to_many :users 10 | has_and_belongs_to_many :skills 11 | belongs_to :stage 12 | belongs_to :project 13 | has_many :projects 14 | 15 | scope :recent, -> { order(last_commented_at: 'desc') } 16 | 17 | scope :recruiting, -> { where.not(stage_id: 13) } 18 | 19 | scope :match_skills, lambda { |skill_ids| 20 | where.not(stage_id: 13) 21 | .includes(:skills) 22 | .where(skills: { id: skill_ids }) 23 | } 24 | 25 | scope :original_order, lambda { |ids| 26 | if Array(ids).empty? 27 | where(id: []) 28 | else 29 | where(id: ids).order("field(id, #{ids.join(',')})") 30 | end 31 | } 32 | 33 | def self.comment_ranking(before) 34 | Project 35 | .joins(:project_updates) 36 | .where( 37 | project_updates: { 38 | created_at: Time.now.ago(30.years)...before 39 | } 40 | ) 41 | .group('project_updates.project_id') 42 | .order('count_project_updates_project_id desc') 43 | .count('project_updates.project_id') 44 | end 45 | 46 | # プロジェクトを編集可能なユーザーかどうか 47 | # @param [Integer] user_id 48 | # @return [Boolean] 49 | def editable_user_id?(user_id) 50 | if user_id == self.user_id 51 | return true 52 | else 53 | return false 54 | end 55 | end 56 | 57 | # 必要なスキルを更新 58 | # @param [Array] skill_names スキル名の配列 59 | # @return [Boolean] 60 | def update_skill_ids_by_skill_names(skill_names) 61 | @before_skill_ids = skills.map(&:id) 62 | @after_skill_ids = [] 63 | skill_names.compact.uniq.reject(&:empty?).each do |skill_name| 64 | skill = Skill.find_by(name: skill_name) 65 | if skill.nil? 66 | skill = Skill.create(name: skill_name) 67 | end 68 | @after_skill_ids.push(skill.id) 69 | end 70 | 71 | # 追加 72 | (@after_skill_ids - @before_skill_ids).each do |skill_id| 73 | skills << Skill.find(skill_id) 74 | end 75 | 76 | # 削除 77 | (@before_skill_ids - @after_skill_ids).each do |skill_id| 78 | skills.delete(skill_id) 79 | end 80 | end 81 | 82 | # メールを送るユーザーを取得 83 | def send_mail_users 84 | send_users = users 85 | me = user 86 | 87 | # 自分がいない場合には含める 88 | if send_users.select { |u| u['user_id'] == me['user_id'] }.empty? 89 | send_users.push me 90 | end 91 | 92 | # すべてを受け取るユーザーを追加 93 | User.where(receive_all: 1).pluck(:email).compact each do |u| 94 | send_users.push u 95 | end 96 | send_users 97 | end 98 | 99 | def send_mail_addresses 100 | send_targets = users.pluck(:email).compact 101 | me = user.email 102 | 103 | # 自分がいない場合には含める 104 | if send_targets.include?(me) 105 | send_targets.push me 106 | end 107 | 108 | # すべてを受け取るユーザーを追加 109 | User.where(receive_all: 1).pluck(:email).compact.each do |u| 110 | send_targets.push u 111 | end 112 | send_targets.uniq 113 | end 114 | 115 | def send_mail_skill_matched_users 116 | Users.find 117 | end 118 | end 119 | -------------------------------------------------------------------------------- /config/routes.rb: -------------------------------------------------------------------------------- 1 | Rails.application.routes.draw do 2 | 3 | get 'sessions/create' 4 | 5 | get 'sessions/destroy' 6 | 7 | # OmniAuth 8 | match 'auth/:provider/callback', to: 'sessions#create', via: 'get' 9 | match 'auth/failure', to: redirect('/'), via: 'get' 10 | match 'signout', to: 'sessions#destroy', as: 'signout', via: 'get' 11 | 12 | resources :project_updates 13 | 14 | get 'top/help', as: 'help' 15 | 16 | get 'auth/logout', as: 'logout' 17 | 18 | post 'auth/signup_check', as: 'signup_check' 19 | 20 | post 'auth/login_check', as: 'login_check' 21 | 22 | get 'auth/signup' 23 | 24 | get 'top/index' 25 | 26 | get 'auth/login', as: 'login' 27 | 28 | get 'auth/signup', as: 'signup' 29 | 30 | get 'user/list', as: 'user_list' 31 | 32 | get 'user/detail/:user_id' => 'user#detail', as: 'user_detail' 33 | 34 | get 'user/edit/:user_id' => 'user#edit', as: 'user_edit' 35 | 36 | get 'project/detail/:project_id' => 'project#detail', as: 'project_detail' 37 | 38 | get 'project/edit', as: 'project_edit' 39 | 40 | get 'project/create', as: 'project_create' 41 | 42 | get 'projects/join/:id', to: 'projects#join' 43 | 44 | get 'projects/leave/:id', to: 'projects#leave' 45 | 46 | get 'projects/posts/:id', to: 'projects#kakikomizu' 47 | 48 | get 'dashboard', to: 'dashboard#index' 49 | 50 | get 'feed' => 'top#feed' 51 | root 'dashboard#index', as: 'root' 52 | 53 | resources :projects 54 | resources :users 55 | 56 | mount LetterOpenerWeb::Engine, at: "/letter_opener" if Rails.env.development? 57 | 58 | # The priority is based upon order of creation: first created -> highest priority. 59 | # See how all your routes lay out with "rake routes". 60 | 61 | # You can have the root of your site routed with "root" 62 | # root 'welcome#index' 63 | 64 | # Example of regular route: 65 | # get 'products/:id' => 'catalog#view' 66 | 67 | # Example of named route that can be invoked with purchase_url(id: product.id) 68 | # get 'products/:id/purchase' => 'catalog#purchase', as: :purchase 69 | 70 | # Example resource route (maps HTTP verbs to controller actions automatically): 71 | # resources :products 72 | 73 | # Example resource route with options: 74 | # resources :products do 75 | # member do 76 | # get 'short' 77 | # post 'toggle' 78 | # end 79 | # 80 | # collection do 81 | # get 'sold' 82 | # end 83 | # end 84 | 85 | # Example resource route with sub-resources: 86 | # resources :products do 87 | # resources :comments, :sales 88 | # resource :seller 89 | # end 90 | 91 | # Example resource route with more complex sub-resources: 92 | # resources :products do 93 | # resources :comments 94 | # resources :sales do 95 | # get 'recent', on: :collection 96 | # end 97 | # end 98 | 99 | # Example resource route with concerns: 100 | # concern :toggleable do 101 | # post 'toggle' 102 | # end 103 | # resources :posts, concerns: :toggleable 104 | # resources :photos, concerns: :toggleable 105 | 106 | # Example resource route within a namespace: 107 | # namespace :admin do 108 | # # Directs /admin/products/* to Admin::ProductsController 109 | # # (app/controllers/admin/products_controller.rb) 110 | # resources :products 111 | # end 112 | end 113 | -------------------------------------------------------------------------------- /app/assets/javascripts/matsu/jquery.sidr.min.js: -------------------------------------------------------------------------------- 1 | /*! Sidr - v1.2.1 - 2013-11-06 2 | * https://github.com/artberri/sidr 3 | * Copyright (c) 2013 Alberto Varela; Licensed MIT */ 4 | (function(e){var t=!1,i=!1,n={isUrl:function(e){var t=RegExp("^(https?:\\/\\/)?((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.)+[a-z]{2,}|((\\d{1,3}\\.){3}\\d{1,3}))(\\:\\d+)?(\\/[-a-z\\d%_.~+]*)*(\\?[;&a-z\\d%_.~+=-]*)?(\\#[-a-z\\d_]*)?$","i");return t.test(e)?!0:!1},loadContent:function(e,t){e.html(t)},addPrefix:function(e){var t=e.attr("id"),i=e.attr("class");"string"==typeof t&&""!==t&&e.attr("id",t.replace(/([A-Za-z0-9_.\-]+)/g,"sidr-id-$1")),"string"==typeof i&&""!==i&&"sidr-inner"!==i&&e.attr("class",i.replace(/([A-Za-z0-9_.\-]+)/g,"sidr-class-$1")),e.removeAttr("style")},execute:function(n,s,a){"function"==typeof s?(a=s,s="sidr"):s||(s="sidr");var r,d,l,c=e("#"+s),u=e(c.data("body")),f=e("html"),p=c.outerWidth(!0),g=c.data("speed"),h=c.data("side"),m=c.data("displace"),v=c.data("onOpen"),y=c.data("onClose"),x="sidr"===s?"sidr-open":"sidr-open "+s+"-open";if("open"===n||"toggle"===n&&!c.is(":visible")){if(c.is(":visible")||t)return;if(i!==!1)return o.close(i,function(){o.open(s)}),void 0;t=!0,"left"===h?(r={left:p+"px"},d={left:"0px"}):(r={right:p+"px"},d={right:"0px"}),u.is("body")&&(l=f.scrollTop(),f.css("overflow-x","hidden").scrollTop(l)),m?u.addClass("sidr-animating").css({width:u.width(),position:"absolute"}).animate(r,g,function(){e(this).addClass(x)}):setTimeout(function(){e(this).addClass(x)},g),c.css("display","block").animate(d,g,function(){t=!1,i=s,"function"==typeof a&&a(s),u.removeClass("sidr-animating")}),v()}else{if(!c.is(":visible")||t)return;t=!0,"left"===h?(r={left:0},d={left:"-"+p+"px"}):(r={right:0},d={right:"-"+p+"px"}),u.is("body")&&(l=f.scrollTop(),f.removeAttr("style").scrollTop(l)),u.addClass("sidr-animating").animate(r,g).removeClass(x),c.animate(d,g,function(){c.removeAttr("style").hide(),u.removeAttr("style"),e("html").removeAttr("style"),t=!1,i=!1,"function"==typeof a&&a(s),u.removeClass("sidr-animating")}),y()}}},o={open:function(e,t){n.execute("open",e,t)},close:function(e,t){n.execute("close",e,t)},toggle:function(e,t){n.execute("toggle",e,t)},toogle:function(e,t){n.execute("toggle",e,t)}};e.sidr=function(t){return o[t]?o[t].apply(this,Array.prototype.slice.call(arguments,1)):"function"!=typeof t&&"string"!=typeof t&&t?(e.error("Method "+t+" does not exist on jQuery.sidr"),void 0):o.toggle.apply(this,arguments)},e.fn.sidr=function(t){var i=e.extend({name:"sidr",speed:200,side:"left",source:null,renaming:!0,body:"body",displace:!0,onOpen:function(){},onClose:function(){}},t),s=i.name,a=e("#"+s);if(0===a.length&&(a=e("
").attr("id",s).appendTo(e("body"))),a.addClass("sidr").addClass(i.side).data({speed:i.speed,side:i.side,body:i.body,displace:i.displace,onOpen:i.onOpen,onClose:i.onClose}),"function"==typeof i.source){var r=i.source(s);n.loadContent(a,r)}else if("string"==typeof i.source&&n.isUrl(i.source))e.get(i.source,function(e){n.loadContent(a,e)});else if("string"==typeof i.source){var d="",l=i.source.split(",");if(e.each(l,function(t,i){d+='
'+e(i).html()+"
"}),i.renaming){var c=e("
").html(d);c.find("*").each(function(t,i){var o=e(i);n.addPrefix(o)}),d=c.html()}n.loadContent(a,d)}else null!==i.source&&e.error("Invalid Sidr Source");return this.each(function(){var t=e(this),i=t.data("sidr");i||(t.data("sidr",s),"ontouchstart"in document.documentElement?(t.bind("touchstart",function(e){e.originalEvent.touches[0],this.touched=e.timeStamp}),t.bind("touchend",function(e){var t=Math.abs(e.timeStamp-this.touched);200>t&&(e.preventDefault(),o.toggle(s))})):t.click(function(e){e.preventDefault(),o.toggle(s)}))})}})(jQuery); -------------------------------------------------------------------------------- /app/views/users/show.html.erb: -------------------------------------------------------------------------------- 1 | <%= provide(:title, t('title.users.show', name: @user.name)) %> 2 | 3 |
4 | <% if notice %> 5 | 8 | <% end %> 9 |
10 |
11 |
<%= image_tag(@user.image) %>
12 |
<%= link_to @user.name, "https://www.facebook.com/app_scoped_user_id/#{@user.uid}/" %>
13 |
14 |
15 |

16 | <%= description_text(@user.description) %> 17 |

18 |
19 | 20 | 21 | <% if authorized? && @my_user.id == @user.id %> 22 | <% if @my_user.email.to_s == '' %> 23 |
24 |
<%= t('dic.email') %>
25 |
26 | <%= t('dic.recommend')%> 27 |
28 |
29 | <% else %> 30 |
31 |
<%= t('dic.email') %>
32 |
33 | <%= @my_user.email %> 34 |
35 |
36 | <% end %> 37 | <% end %> 38 | 39 | 40 |
41 |
参加中
42 |
43 | <% @user.projects.each do |project| %> 44 | <%= link_to( project.subject, project_url(id: project.id)) %> 45 | <% if project != @user.projects.last %> 46 | , 47 | <% end %> 48 | <% end %> 49 |
50 |
51 | 52 | 53 |
54 |
作成した課題の数
55 |
56 | <%= Project.where(user_id: @user.id).count %> 57 |
58 |
59 | 60 | 61 |
62 |
参加している課題の数
63 |
64 | <%= @user.projects.count %> 65 |
66 |
67 | 68 | 69 |
70 |
コメントした数
71 |
72 | <%= @user.project_updates.count %> 73 |
74 |
75 | 76 | 77 | 78 |
79 |
スキル
80 |
81 | <% @user.skills.each do |s| %> 82 | <%= link_to users_path(skill_id: s.id) do %> 83 | <%= s.name %> 84 | <% end %> 85 | <% end %> 86 |
87 |
88 |
89 |
90 | 91 | <% if authorized? && @my_user.id == @user.id %> 92 |
<%= link_to t('.edit'), edit_user_path(@user) %>
93 | <% end %> 94 |
95 | 96 | 97 |
98 |
直近コメント(10)
99 |
100 | <% @my_comments.each do |comment| %> 101 |

102 | <%= link_to comment.project.subject, project_path(comment.project.id, anchor: "comment-#{comment.id}") %> ( <%= time_ago_in_words comment.created_at %> ) 103 |

104 | <% end %> 105 |
106 |
107 |
108 | -------------------------------------------------------------------------------- /app/views/shared/_project.html.erb: -------------------------------------------------------------------------------- 1 |
2 |
3 |
<%= link_to(project.subject, project_path(id: project.id)) %>
4 |
<%= link_to (image_tag project.user.image, alt: project.user.name, title: project.user.name), user_path(id:project.user.id) %>
5 |
6 | <%= name_and_link(project.user) %><% t('dic.title') %>
7 | <%= created_at_ago(project) %> <% t('dic.posted_on') %> 8 |
9 |
10 |
11 | <%=description_text(project.description)%> 12 |
13 | 14 | 15 |
16 |
17 | SNSシェア 18 |
19 |
20 | <%= facebook_share_btn(project_path(id: project.id)) %> 21 |
22 |
23 | 24 | 25 | <% if project.user_url.present? %> 26 |
27 |
<%= t('dic.url') %>
28 |
29 | <%= link_to_if project.user_url.present?, project.user_url, project.user_url do %> 30 | <%= t('dic.url') %>はありません 31 | <% end %> 32 |
33 |
34 | <% end %> 35 | 36 | 37 | <% if project.development_url.present? %> 38 |
39 |
<%= t('dic.dev_url') %>
40 |
41 | <%= link_to_if project.development_url.present?, project.development_url, project.development_url do %> 42 | <%= t('dic.dev_url') %>はありません 43 | <% end %> 44 |
45 |
46 | <% end %> 47 | 48 | 49 |
50 |
<%= t('dic.status') %>
51 |
<%= link_to project.stage.name, ENV['LINK_ABOUT_PROJECT_STATUS'], target: '_blank' %>
52 |
53 | 54 | 55 | <% if project.project.present? %> 56 |
57 |
<%= t('dic.parent_project') %>
58 |
59 | <% if project.project.present? %> 60 | <%= link_to project.project.subject, project_path(id: project.project.id) %> 61 | <% end %> 62 |
63 |
64 | <% end %> 65 | 66 | 67 | <% if project.projects.present? %> 68 |
69 |
<%= t('dic.child_project') %>
70 |
71 | <% project.projects.each do |p| %> 72 | <%= link_to p.subject, project_path(id: p.id) %>
73 | <% end %> 74 |
75 |
76 | <% end %> 77 | 78 | 79 |
80 |
<%= t('dic.wantskill') %>
81 |
82 | <% project.skills.each do |s| %> 83 | <%= link_to users_path(skill_id: s.id) do %> 84 | <%= s.name %> 85 | <% end %> 86 | <% end %> 87 |
88 |
89 | 90 | 91 |
92 |
参加者一覧
93 |
94 | <% project.users.each do |user| %> 95 | <%= link_to image_tag(user.image, alt: user.name, title: user.name), user_path(id: user.id) %> 96 | <% end %> 97 |
98 |
99 |
100 | -------------------------------------------------------------------------------- /config/environments/production.rb: -------------------------------------------------------------------------------- 1 | Rails.application.configure do 2 | # Settings specified here will take precedence over those in config/application.rb. 3 | 4 | # Code is not reloaded between requests. 5 | config.cache_classes = true 6 | 7 | # Eager load code on boot. This eager loads most of Rails and 8 | # your application in memory, allowing both threaded web servers 9 | # and those relying on copy on write to perform better. 10 | # Rake tasks automatically ignore this option for performance. 11 | config.eager_load = true 12 | 13 | # Full error reports are disabled and caching is turned on. 14 | config.consider_all_requests_local = false 15 | config.action_controller.perform_caching = true 16 | 17 | # Disable serving static files from the `/public` folder by default since 18 | # Apache or NGINX already handles this. 19 | config.public_file_server.enabled = ENV['RAILS_SERVE_STATIC_FILES'].present? 20 | 21 | # Compress JavaScripts and CSS. 22 | config.assets.js_compressor = :uglifier 23 | # config.assets.css_compressor = :sass 24 | 25 | # Do not fallback to assets pipeline if a precompiled asset is missed. 26 | config.assets.compile = false 27 | 28 | # `config.assets.precompile` and `config.assets.version` have moved to config/initializers/assets.rb 29 | 30 | # Enable serving of images, stylesheets, and JavaScripts from an asset server. 31 | # config.action_controller.asset_host = 'http://assets.example.com' 32 | 33 | # Specifies the header that your server uses for sending files. 34 | # config.action_dispatch.x_sendfile_header = 'X-Sendfile' # for Apache 35 | # config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for NGINX 36 | 37 | # Mount Action Cable outside main process or domain 38 | # config.action_cable.mount_path = nil 39 | # config.action_cable.url = 'wss://example.com/cable' 40 | # config.action_cable.allowed_request_origins = [ 'http://example.com', /http:\/\/example.*/ ] 41 | 42 | # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies. 43 | # config.force_ssl = true 44 | 45 | # Use the lowest log level to ensure availability of diagnostic information 46 | # when problems arise. 47 | config.log_level = :debug 48 | 49 | # Prepend all log lines with the following tags. 50 | config.log_tags = [ :request_id ] 51 | 52 | # Use a different cache store in production. 53 | # config.cache_store = :mem_cache_store 54 | 55 | # Use a real queuing backend for Active Job (and separate queues per environment) 56 | # config.active_job.queue_adapter = :resque 57 | # config.active_job.queue_name_prefix = "ha4go_#{Rails.env}" 58 | config.action_mailer.perform_caching = false 59 | 60 | # Ignore bad email addresses and do not raise email delivery errors. 61 | # Set this to true and configure the email server for immediate delivery to raise delivery errors. 62 | config.action_mailer.raise_delivery_errors = false 63 | config.action_mailer.delivery_method = :smtp 64 | config.action_mailer.smtp_settings = { 65 | address: Rails.application.secrets.smtp_address, 66 | port: Rails.application.secrets.smtp_port, 67 | domain: Rails.application.secrets.smtp_domain, 68 | user_name: Rails.application.secrets.smtp_user_name, 69 | password: Rails.application.secrets.smtp_password, 70 | authentication: :plain, 71 | enable_starttls_auto: true, 72 | openssl_verify_mode: 'none' 73 | } 74 | 75 | config.action_mailer.default_url_options = { 76 | host: ENV['APP_HOST'] 77 | } 78 | # config.action_mailer.raise_delivery_errors = false 79 | 80 | # Enable locale fallbacks for I18n (makes lookups for any locale fall back to 81 | # the I18n.default_locale when a translation cannot be found). 82 | config.i18n.fallbacks = true 83 | 84 | # Send deprecation notices to registered listeners. 85 | config.active_support.deprecation = :notify 86 | 87 | # Use default logging formatter so that PID and timestamp are not suppressed. 88 | config.log_formatter = ::Logger::Formatter.new 89 | 90 | # Use a different logger for distributed setups. 91 | # require 'syslog/logger' 92 | # config.logger = ActiveSupport::TaggedLogging.new(Syslog::Logger.new 'app-name') 93 | 94 | if ENV["RAILS_LOG_TO_STDOUT"].present? 95 | logger = ActiveSupport::Logger.new(STDOUT) 96 | logger.formatter = config.log_formatter 97 | config.logger = ActiveSupport::TaggedLogging.new(logger) 98 | end 99 | 100 | # Do not dump schema after migrations. 101 | config.active_record.dump_schema_after_migration = false 102 | 103 | GA.tracker = Rails.application.secrets.ga_track_id 104 | end 105 | -------------------------------------------------------------------------------- /app/assets/javascripts/skill_quick_add.js: -------------------------------------------------------------------------------- 1 | var hankana2zenkana = function (str) { 2 | var kanaMap = { 3 | 'ガ': 'ガ', 'ギ': 'ギ', 'グ': 'グ', 'ゲ': 'ゲ', 'ゴ': 'ゴ', 4 | 'ザ': 'ザ', 'ジ': 'ジ', 'ズ': 'ズ', 'ゼ': 'ゼ', 'ゾ': 'ゾ', 5 | 'ダ': 'ダ', 'ヂ': 'ヂ', 'ヅ': 'ヅ', 'デ': 'デ', 'ド': 'ド', 6 | 'バ': 'バ', 'ビ': 'ビ', 'ブ': 'ブ', 'ベ': 'ベ', 'ボ': 'ボ', 7 | 'パ': 'パ', 'ピ': 'ピ', 'プ': 'プ', 'ペ': 'ペ', 'ポ': 'ポ', 8 | 'ヴ': 'ヴ', 'ヷ': 'ヷ', 'ヺ': 'ヺ', 9 | 'ア': 'ア', 'イ': 'イ', 'ウ': 'ウ', 'エ': 'エ', 'オ': 'オ', 10 | 'カ': 'カ', 'キ': 'キ', 'ク': 'ク', 'ケ': 'ケ', 'コ': 'コ', 11 | 'サ': 'サ', 'シ': 'シ', 'ス': 'ス', 'セ': 'セ', 'ソ': 'ソ', 12 | 'タ': 'タ', 'チ': 'チ', 'ツ': 'ツ', 'テ': 'テ', 'ト': 'ト', 13 | 'ナ': 'ナ', 'ニ': 'ニ', 'ヌ': 'ヌ', 'ネ': 'ネ', 'ノ': 'ノ', 14 | 'ハ': 'ハ', 'ヒ': 'ヒ', 'フ': 'フ', 'ヘ': 'ヘ', 'ホ': 'ホ', 15 | 'マ': 'マ', 'ミ': 'ミ', 'ム': 'ム', 'メ': 'メ', 'モ': 'モ', 16 | 'ヤ': 'ヤ', 'ユ': 'ユ', 'ヨ': 'ヨ', 17 | 'ラ': 'ラ', 'リ': 'リ', 'ル': 'ル', 'レ': 'レ', 'ロ': 'ロ', 18 | 'ワ': 'ワ', 'ヲ': 'ヲ', 'ン': 'ン', 19 | 'ァ': 'ァ', 'ィ': 'ィ', 'ゥ': 'ゥ', 'ェ': 'ェ', 'ォ': 'ォ', 20 | 'ッ': 'ッ', 'ャ': 'ャ', 'ュ': 'ュ', 'ョ': 'ョ', 21 | '。': '。', '、': '、', 'ー': 'ー', '「': '「', '」': '」', '・': '・' 22 | }; 23 | 24 | var reg = new RegExp('(' + Object.keys(kanaMap).join('|') + ')', 'g'); 25 | return str 26 | .replace(reg, function (match) { 27 | return kanaMap[match]; 28 | }) 29 | .replace(/゙/g, '゛') 30 | .replace(/゚/g, '゜'); 31 | }; 32 | 33 | /** 34 | * 全角から半角に置き換え 35 | * 36 | * 全角チルダ、全角波ダッシュ共に半角チルダに変換 37 | * 全角ハイフン、全角ダッシュ、全角マイナス記号は半角ハイフンに変換 38 | * 長音符は半角ハイフンに含めない(住所の地名等に使用される為) 39 | * 40 | * 今は良いがUnicode 8.0で波ダッシュの形が変わるみたいなので、波ダッシュを変換に 41 | * 含めるべきかどうかは検討が必要 42 | * 43 | * @param {String} str 変換したい文字列 44 | * @param {Boolean} tilde チルダ falseを指定した場合は変換なし 45 | * @param {Boolean} mark 記号 falseを指定した場合は変換なし 46 | * @param {Boolean} hankana 半角カナ記号 trueを指定した場合のみ変換 47 | * @param {Boolean} space スペース falseを指定した場合は変換なし 48 | * @param {Boolean} alpha 英字 falseを指定した場合は変換なし 49 | * @param {Boolean} num 数字 falseを指定した場合は変換なし 50 | */ 51 | var zen2han = function (str, tilde, mark, hankana, space, alpha, num) { 52 | if (alpha !== false) { 53 | str = str.replace(/[A-Za-z]/g, function (s) { 54 | return String.fromCharCode(s.charCodeAt(0) - 65248); 55 | }); 56 | } 57 | if (num !== false) { 58 | str = str.replace(/[0-9]/g, function (s) { 59 | return String.fromCharCode(s.charCodeAt(0) - 65248); 60 | }); 61 | } 62 | if (mark !== false) { 63 | var reg = /[!"#$%&'()*+,-./:;<=>?@[\]^_`{|}]/g; 64 | str = str.replace(reg, function (s) { 65 | return String.fromCharCode(s.charCodeAt(0) - 65248); 66 | }).replace(/[‐-―]/g, '-'); 67 | } 68 | if (tilde !== false) { 69 | str = str.replace(/[~〜]/g, '~'); 70 | } 71 | if (space !== false) { 72 | str = str.replace(/ /g, ' '); 73 | } 74 | if (hankana === true) { 75 | var map = {'。': '。', '、': '、', '「': '「', '」': '」', '・': '・'}; 76 | var reg = new RegExp('(' + Object.keys(map).join('|') + ')', 'g'); 77 | str = str.replace(reg, function (match) { 78 | return map[match]; 79 | }); 80 | } 81 | return str; 82 | }; 83 | 84 | $(function(){ 85 | $('.quick-add__item').on('click', remove_item); 86 | $('.quick-add__btn').on('click', add_item); 87 | }); 88 | 89 | var remove_item = function() { 90 | $(this).attr('disabled', 'disabled'); 91 | $(this).find('.quick-add__hidden').remove(); 92 | }; 93 | 94 | var add_item = function() { 95 | var template = $(this).parents('.quick-add').find('.quick-add__item--template').last().clone(); 96 | var text = $('.quick-add__input').val().trim(); 97 | if (text == '' || is_duplicate(text)) { 98 | return false; 99 | } 100 | template.show(); 101 | template.removeAttr('disabled'); 102 | template.find('.quick-add__item-name').text(text); 103 | template.find('.quick-add__hidden').val(text); 104 | template.find('.quick-add__hidden').attr('name', 'skill_names[]'); 105 | $('.quick-add__list').append(template); 106 | $('.quick-add__item').on('click', remove_item); 107 | return true; 108 | }; 109 | 110 | var current_items = function(normalizer) { 111 | var list = $('input.quick-add__hidden'); 112 | var items = []; 113 | for( var i = 0; i < list.length; i++) { 114 | items.push(normalizer(list[i].defaultValue)); 115 | } 116 | return items; 117 | }; 118 | 119 | var normalized_string = function(t) { 120 | return hankana2zenkana( 121 | zen2han( 122 | t.toUpperCase(), 123 | true, 124 | true, 125 | true, 126 | true, 127 | true, 128 | true)); 129 | }; 130 | 131 | var is_duplicate = function(input_name) { 132 | return find_normalized_value(input_name) > 0; 133 | }; 134 | 135 | var find_normalized_value = function(input_name) { 136 | return current_items(normalized_string).indexOf(normalized_string(input_name)); 137 | }; 138 | -------------------------------------------------------------------------------- /config/locales/defaults/ja.yml: -------------------------------------------------------------------------------- 1 | --- 2 | ja: 3 | date: 4 | abbr_day_names: 5 | - 日 6 | - 月 7 | - 火 8 | - 水 9 | - 木 10 | - 金 11 | - 土 12 | abbr_month_names: 13 | - 14 | - 1月 15 | - 2月 16 | - 3月 17 | - 4月 18 | - 5月 19 | - 6月 20 | - 7月 21 | - 8月 22 | - 9月 23 | - 10月 24 | - 11月 25 | - 12月 26 | day_names: 27 | - 日曜日 28 | - 月曜日 29 | - 火曜日 30 | - 水曜日 31 | - 木曜日 32 | - 金曜日 33 | - 土曜日 34 | formats: 35 | default: "%Y/%m/%d" 36 | long: "%Y年%m月%d日(%a)" 37 | short: "%m/%d" 38 | month_names: 39 | - 40 | - 1月 41 | - 2月 42 | - 3月 43 | - 4月 44 | - 5月 45 | - 6月 46 | - 7月 47 | - 8月 48 | - 9月 49 | - 10月 50 | - 11月 51 | - 12月 52 | order: 53 | - :year 54 | - :month 55 | - :day 56 | datetime: 57 | distance_in_words: 58 | about_x_hours: 59 | one: 約1時間前 60 | other: 約%{count}時間前 61 | about_x_months: 62 | one: 約1ヶ月前 63 | other: 約%{count}ヶ月前 64 | about_x_years: 65 | one: 約1年前 66 | other: 約%{count}年前 67 | almost_x_years: 68 | one: 1年弱前 69 | other: "%{count}年弱前" 70 | half_a_minute: 30秒前後前 71 | less_than_x_minutes: 72 | one: 1分以内前 73 | other: "%{count}分未満前" 74 | less_than_x_seconds: 75 | one: 1秒以内前 76 | other: "%{count}秒未満前" 77 | over_x_years: 78 | one: 1年以上前 79 | other: "%{count}年以上前" 80 | x_days: 81 | one: 1日前 82 | other: "%{count}日前" 83 | x_minutes: 84 | one: 1分前 85 | other: "%{count}分前" 86 | x_months: 87 | one: 1ヶ月前 88 | other: "%{count}ヶ月前" 89 | x_seconds: 90 | one: 1秒前 91 | other: "%{count}秒前" 92 | prompts: 93 | day: 日 94 | hour: 時 95 | minute: 分 96 | month: 月 97 | second: 秒 98 | year: 年 99 | errors: 100 | format: "%{attribute}%{message}" 101 | messages: 102 | accepted: を受諾してください 103 | blank: を入力してください 104 | present: は入力しないでください 105 | confirmation: と%{attribute}の入力が一致しません 106 | empty: を入力してください 107 | equal_to: は%{count}にしてください 108 | even: は偶数にしてください 109 | exclusion: は予約されています 110 | greater_than: は%{count}より大きい値にしてください 111 | greater_than_or_equal_to: は%{count}以上の値にしてください 112 | inclusion: は一覧にありません 113 | invalid: は不正な値です 114 | less_than: は%{count}より小さい値にしてください 115 | less_than_or_equal_to: は%{count}以下の値にしてください 116 | not_a_number: は数値で入力してください 117 | not_an_integer: は整数で入力してください 118 | odd: は奇数にしてください 119 | record_invalid: バリデーションに失敗しました %{errors} 120 | restrict_dependent_destroy: "%{record}が存在しているので削除できません" 121 | taken: はすでに存在します 122 | too_long: は%{count}文字以内で入力してください 123 | too_short: は%{count}文字以上で入力してください 124 | wrong_length: は%{count}文字で入力してください 125 | other_than: は%{count}以外の値にしてください 126 | template: 127 | body: 次の項目を確認してください 128 | header: 129 | one: "%{model}にエラーが発生しました。" 130 | other: "%{model}に%{count}個のエラーが発生しました" 131 | helpers: 132 | select: 133 | prompt: 選択してください 134 | submit: 135 | create: 登録する 136 | submit: 保存する 137 | update: 更新する 138 | number: 139 | currency: 140 | format: 141 | delimiter: "," 142 | format: "%n%u" 143 | precision: 0 144 | separator: "." 145 | significant: false 146 | strip_insignificant_zeros: false 147 | unit: 円 148 | format: 149 | delimiter: "," 150 | precision: 3 151 | separator: "." 152 | significant: false 153 | strip_insignificant_zeros: false 154 | human: 155 | decimal_units: 156 | format: "%n %u" 157 | units: 158 | billion: 十億 159 | million: 百万 160 | quadrillion: 千兆 161 | thousand: 千 162 | trillion: 兆 163 | unit: '' 164 | format: 165 | delimiter: '' 166 | precision: 3 167 | significant: true 168 | strip_insignificant_zeros: true 169 | storage_units: 170 | format: "%n%u" 171 | units: 172 | byte: バイト 173 | gb: ギガバイト 174 | kb: キロバイト 175 | mb: メガバイト 176 | tb: テラバイト 177 | percentage: 178 | format: 179 | delimiter: '' 180 | format: "%n%" 181 | precision: 182 | format: 183 | delimiter: '' 184 | support: 185 | array: 186 | last_word_connector: と 187 | two_words_connector: と 188 | words_connector: と 189 | time: 190 | am: 午前 191 | formats: 192 | default: "%Y/%m/%d %H:%M:%S" 193 | long: "%Y年%m月%d日(%a) %H時%M分%S秒 %z" 194 | short: "%y/%m/%d %H:%M" 195 | pm: 午後 196 | -------------------------------------------------------------------------------- /db/schema.rb: -------------------------------------------------------------------------------- 1 | # This file is auto-generated from the current state of the database. Instead 2 | # of editing this file, please use the migrations feature of Active Record to 3 | # incrementally modify your database, and then regenerate this schema definition. 4 | # 5 | # Note that this schema.rb definition is the authoritative source for your 6 | # database schema. If you need to create the application database on another 7 | # system, you should be using db:schema:load, not running all the migrations 8 | # from scratch. The latter is a flawed and unsustainable approach (the more migrations 9 | # you'll amass, the slower it'll run and the greater likelihood for issues). 10 | # 11 | # It's strongly recommended that you check this file into your version control system. 12 | 13 | ActiveRecord::Schema.define(version: 2017_05_07_011046) do 14 | 15 | create_table "app_informations", id: :integer, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8", force: :cascade do |t| 16 | t.date "release" 17 | t.text "description" 18 | t.datetime "created_at", null: false 19 | t.datetime "updated_at", null: false 20 | end 21 | 22 | create_table "delayed_jobs", id: :integer, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8", force: :cascade do |t| 23 | t.integer "priority", default: 0, null: false 24 | t.integer "attempts", default: 0, null: false 25 | t.text "handler", null: false 26 | t.text "last_error" 27 | t.datetime "run_at" 28 | t.datetime "locked_at" 29 | t.datetime "failed_at" 30 | t.string "locked_by" 31 | t.string "queue" 32 | t.datetime "created_at" 33 | t.datetime "updated_at" 34 | t.index ["priority", "run_at"], name: "delayed_jobs_priority" 35 | end 36 | 37 | create_table "project_update_histories", id: :integer, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8", force: :cascade do |t| 38 | t.integer "project_update_id" 39 | t.integer "user_id" 40 | t.datetime "created_at", null: false 41 | t.datetime "updated_at", null: false 42 | t.index ["project_update_id"], name: "index_project_update_histories_on_project_update_id" 43 | t.index ["user_id"], name: "index_project_update_histories_on_user_id" 44 | end 45 | 46 | create_table "project_updates", id: :integer, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8", force: :cascade do |t| 47 | t.integer "project_id" 48 | t.text "description" 49 | t.datetime "created_at", null: false 50 | t.datetime "updated_at", null: false 51 | t.integer "user_id" 52 | t.boolean "freezing" 53 | t.string "comment_image" 54 | end 55 | 56 | create_table "projects", id: :integer, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8", force: :cascade do |t| 57 | t.integer "user_id" 58 | t.integer "stage_id", default: 10, null: false 59 | t.string "subject" 60 | t.text "description" 61 | t.string "user_url" 62 | t.string "development_url" 63 | t.datetime "created_at", null: false 64 | t.datetime "updated_at", null: false 65 | t.integer "project_id" 66 | t.datetime "last_commented_at" 67 | t.text "images" 68 | t.index ["project_id"], name: "index_projects_on_project_id" 69 | end 70 | 71 | create_table "projects_skills", id: :integer, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8", force: :cascade do |t| 72 | t.integer "project_id" 73 | t.integer "skill_id" 74 | t.datetime "created_at", null: false 75 | t.datetime "updated_at", null: false 76 | end 77 | 78 | create_table "projects_users", id: :integer, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8", force: :cascade do |t| 79 | t.integer "project_id" 80 | t.integer "user_id" 81 | t.datetime "created_at", null: false 82 | t.datetime "updated_at", null: false 83 | t.index ["user_id", "project_id"], name: "index_projects_users_on_user_id_and_project_id", unique: true 84 | end 85 | 86 | create_table "skills", id: :integer, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8", force: :cascade do |t| 87 | t.string "name" 88 | t.datetime "created_at", null: false 89 | t.datetime "updated_at", null: false 90 | t.index ["name"], name: "index_skills_on_name", unique: true 91 | end 92 | 93 | create_table "skills_users", id: :integer, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8", force: :cascade do |t| 94 | t.integer "user_id" 95 | t.integer "skill_id" 96 | t.datetime "created_at", null: false 97 | t.datetime "updated_at", null: false 98 | end 99 | 100 | create_table "stages", id: :integer, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8", force: :cascade do |t| 101 | t.string "name" 102 | t.datetime "created_at", null: false 103 | t.datetime "updated_at", null: false 104 | end 105 | 106 | create_table "users", id: :integer, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8", force: :cascade do |t| 107 | t.string "name" 108 | t.string "email" 109 | t.text "description" 110 | t.datetime "created_at", null: false 111 | t.datetime "updated_at", null: false 112 | t.string "provider" 113 | t.string "uid" 114 | t.string "oauth_token" 115 | t.datetime "oauth_expires_at" 116 | t.string "image" 117 | t.boolean "receive_all" 118 | end 119 | 120 | add_foreign_key "project_update_histories", "project_updates" 121 | add_foreign_key "project_update_histories", "users" 122 | add_foreign_key "projects", "projects" 123 | end 124 | -------------------------------------------------------------------------------- /app/views/projects/_form.html.erb: -------------------------------------------------------------------------------- 1 | <%= form_for(@project, html: { multipart: true }) do |f| %> 2 | <%= hidden_field_tag :from, @from.to_s %> 3 | 4 | <% if @project.errors.any? %> 5 |
6 |

<%= pluralize(@project.errors.count, "error") %> prohibited this project from being saved:

7 |
    8 | <% @project.errors.full_messages.each do |message| %> 9 |
  • <%= message %>
  • 10 | <% end %> 11 |
12 |
13 | <% end %> 14 |
15 | 16 |
17 | <% if @parent_project.nil? %> 18 | <% else %> 19 | <%= f.hidden_field :project_id, value: @parent_project.id %> 20 | <% end %> 21 |
22 | <%= t 'dic.title' %> 23 |
24 |
25 | <%= f.text_field :subject, placeholder: t('dic.ex_subject') %> 26 |
27 |
28 | 29 | 30 |
31 |
32 | URL 33 |
34 |
35 | <%= f.url_field :user_url, class: 'form-control', placeholder: t('dic.ex_url') %> 36 |
37 |
38 | 39 | 40 |
41 |
42 | <%= t '.dev_url' %> 43 |
44 |
45 |

46 | <%= f.url_field :development_url, class: 'form-control', placeholder: t('dic.ex_devurl') %> 47 |

48 |

49 | <%= t('.recommend_dev_url')%> 50 |

51 |
52 |
53 | 54 | 55 |
56 |
57 | <%= t 'dic.detail' %> 58 |
59 |
60 | <%= f.text_area :description, class: 'form-control', rows: 5, placeholder: t('dic.ex_description') %> 61 |
62 |
63 | 64 | 65 | <% if (params[:action] == 'edit') %> 66 |
67 |
68 | 画像一覧 69 |
70 |
71 | <% if @project.images.size == 0 %> 72 | なし 73 | <% else %> 74 | <%= f.label "remove_images" do %> 75 | <%= f.check_box(:remove_images) + "添付画像を全て削除する" %> 76 | <% end %> 77 | <% @project.images.each_with_index do |img, index| %> 78 |
79 |

80 | <%= image_tag(img.url) %> 81 |

82 |
83 | <% end %> 84 | <% end %> 85 |
86 |
87 | <% end %> 88 | 89 | 90 |
91 |
92 | 画像添付 93 |
94 |
95 | <%= f.file_field :images, multiple: true %> 96 |
97 |
98 | 99 | 100 | 101 |
102 |
103 | <%= t '.skill'%> 104 |
105 |
106 |

107 | <%= collection_check_boxes(:skill_names, :skill_ids, Skill.all, :name, :name) do |b| %> 108 | <%= b.label { b.check_box(checked: @my_skills.include?(b.text)) + b.text } %> 109 | <% end %> 110 |

111 |

112 | <%= t('.recommend_skill')%> 113 |

114 |
115 |
116 | 117 | 118 |
119 |
120 | <%= t '.new_skill'%> 121 |
122 |
123 | <%= text_field :new_skills, :new_skills, placeholder: t('dic.ex_skills') %> 124 |
125 |
126 | <% if (params[:action] == 'edit') then %> 127 |
128 |
129 | <%= t 'dic.status' %> <%= link_to t('dic.detail'), ENV['LINK_ABOUT_PROJECT_STATUS'], target: '_blank' %> 130 |
131 |
132 |
133 | <%= f.select :stage_id, @stages.map{ |stage| [stage.name, stage.id] }, :selected => @project.stage_id %> 134 |
135 |
136 |
137 | <% end %> 138 |
139 | 140 | 141 | <% if (params[:action] == 'edit') then %> 142 |
143 | 146 |
147 | <% else %> 148 |
149 | 153 |
154 |
155 | 158 |
159 | <% end %> 160 | <% end %> 161 | -------------------------------------------------------------------------------- /config/locales/defaults/en.yml: -------------------------------------------------------------------------------- 1 | --- 2 | en: 3 | date: 4 | abbr_day_names: 5 | - Sun 6 | - Mon 7 | - Tue 8 | - Wed 9 | - Thu 10 | - Fri 11 | - Sat 12 | abbr_month_names: 13 | - 14 | - Jan 15 | - Feb 16 | - Mar 17 | - Apr 18 | - May 19 | - Jun 20 | - Jul 21 | - Aug 22 | - Sep 23 | - Oct 24 | - Nov 25 | - Dec 26 | day_names: 27 | - Sunday 28 | - Monday 29 | - Tuesday 30 | - Wednesday 31 | - Thursday 32 | - Friday 33 | - Saturday 34 | formats: 35 | default: "%Y-%m-%d" 36 | long: "%B %d, %Y" 37 | short: "%b %d" 38 | month_names: 39 | - 40 | - January 41 | - February 42 | - March 43 | - April 44 | - May 45 | - June 46 | - July 47 | - August 48 | - September 49 | - October 50 | - November 51 | - December 52 | order: 53 | - :year 54 | - :month 55 | - :day 56 | datetime: 57 | distance_in_words: 58 | about_x_hours: 59 | one: about 1 hour 60 | other: about %{count} hours 61 | about_x_months: 62 | one: about 1 month 63 | other: about %{count} months 64 | about_x_years: 65 | one: about 1 year 66 | other: about %{count} years 67 | almost_x_years: 68 | one: almost 1 year 69 | other: almost %{count} years 70 | half_a_minute: half a minute 71 | less_than_x_minutes: 72 | one: less than a minute 73 | other: less than %{count} minutes 74 | less_than_x_seconds: 75 | one: less than 1 second 76 | other: less than %{count} seconds 77 | over_x_years: 78 | one: over 1 year 79 | other: over %{count} years 80 | x_days: 81 | one: 1 day 82 | other: "%{count} days" 83 | x_minutes: 84 | one: 1 minute 85 | other: "%{count} minutes" 86 | x_months: 87 | one: 1 month 88 | other: "%{count} months" 89 | x_seconds: 90 | one: 1 second 91 | other: "%{count} seconds" 92 | prompts: 93 | day: Day 94 | hour: Hour 95 | minute: Minute 96 | month: Month 97 | second: Seconds 98 | year: Year 99 | errors: 100 | format: "%{attribute} %{message}" 101 | messages: 102 | accepted: must be accepted 103 | blank: can't be blank 104 | present: must be blank 105 | confirmation: doesn't match %{attribute} 106 | empty: can't be empty 107 | equal_to: must be equal to %{count} 108 | even: must be even 109 | exclusion: is reserved 110 | greater_than: must be greater than %{count} 111 | greater_than_or_equal_to: must be greater than or equal to %{count} 112 | inclusion: is not included in the list 113 | invalid: is invalid 114 | less_than: must be less than %{count} 115 | less_than_or_equal_to: must be less than or equal to %{count} 116 | not_a_number: is not a number 117 | not_an_integer: must be an integer 118 | odd: must be odd 119 | record_invalid: 'Validation failed: %{errors}' 120 | restrict_dependent_destroy: 121 | one: Cannot delete record because a dependent %{record} exists 122 | many: Cannot delete record because dependent %{record} exist 123 | taken: has already been taken 124 | too_long: 125 | one: is too long (maximum is 1 character) 126 | other: is too long (maximum is %{count} characters) 127 | too_short: 128 | one: is too short (minimum is 1 character) 129 | other: is too short (minimum is %{count} characters) 130 | wrong_length: 131 | one: is the wrong length (should be 1 character) 132 | other: is the wrong length (should be %{count} characters) 133 | other_than: must be other than %{count} 134 | template: 135 | body: 'There were problems with the following fields:' 136 | header: 137 | one: 1 error prohibited this %{model} from being saved 138 | other: "%{count} errors prohibited this %{model} from being saved" 139 | helpers: 140 | select: 141 | prompt: Please select 142 | submit: 143 | create: Create %{model} 144 | submit: Save %{model} 145 | update: Update %{model} 146 | number: 147 | currency: 148 | format: 149 | delimiter: "," 150 | format: "%u%n" 151 | precision: 2 152 | separator: "." 153 | significant: false 154 | strip_insignificant_zeros: false 155 | unit: "$" 156 | format: 157 | delimiter: "," 158 | precision: 3 159 | separator: "." 160 | significant: false 161 | strip_insignificant_zeros: false 162 | human: 163 | decimal_units: 164 | format: "%n %u" 165 | units: 166 | billion: Billion 167 | million: Million 168 | quadrillion: Quadrillion 169 | thousand: Thousand 170 | trillion: Trillion 171 | unit: '' 172 | format: 173 | delimiter: '' 174 | precision: 3 175 | significant: true 176 | strip_insignificant_zeros: true 177 | storage_units: 178 | format: "%n %u" 179 | units: 180 | byte: 181 | one: Byte 182 | other: Bytes 183 | gb: GB 184 | kb: KB 185 | mb: MB 186 | tb: TB 187 | percentage: 188 | format: 189 | delimiter: '' 190 | format: "%n%" 191 | precision: 192 | format: 193 | delimiter: '' 194 | support: 195 | array: 196 | last_word_connector: ", and " 197 | two_words_connector: " and " 198 | words_connector: ", " 199 | time: 200 | am: am 201 | formats: 202 | default: "%a, %d %b %Y %H:%M:%S %z" 203 | long: "%B %d, %Y %H:%M" 204 | short: "%d %b %H:%M" 205 | pm: pm 206 | -------------------------------------------------------------------------------- /app/assets/javascripts/matsu/jquery.mobile-menu.js: -------------------------------------------------------------------------------- 1 | /* Mobile Menu jQuery Plugin 2 | * 3 | * Creates a side nav bar that mimics the native IOS nav slide drawer 4 | * 5 | * Author: Nick Brewer 6 | * Version: 0.5 7 | * 8 | * REQUIRES: jQuery 9 | */ 10 | 11 | var mobileApp = mobileApp || {}; 12 | 13 | ;(function(mobileApp,$){ 14 | var MobileMenu = function(elem, options){ 15 | this.elem = elem; 16 | this.$elem = $(elem); 17 | this.options = options; 18 | }; 19 | 20 | MobileMenu.prototype = { 21 | defaults: { 22 | page_id: 'build-menu-page', 23 | menu: '', // set as an array for multiple menus 24 | menu_width: 260, 25 | menu_id: "mobile-nav", 26 | button_content: 'MENU', 27 | prepend_button_to: '', 28 | menu_bar: '' 29 | }, 30 | 31 | /* 32 | * Initiate app. Set Layout. 33 | * 34 | * @return this 35 | */ 36 | init: function(){ 37 | var _this = this; 38 | _this.config = $.extend({}, _this.defaults, _this.options); 39 | 40 | if($(_this.config.menu_id).length === 0){ 41 | this.setLayout(); 42 | } 43 | 44 | return _this; 45 | }, 46 | 47 | /* 48 | * Clone site navigation and set it as mobile nav, set Class on each new menu 49 | * 50 | * @return false if no menu option is provided 51 | */ 52 | 53 | buildMenu: function(){ 54 | var _this = this; 55 | _this.config = $.extend({}, _this.defaults, _this.options); 56 | var menu = _this.config.menu, 57 | mobile_menu = $("#build-menu"), 58 | menu_collection = []; 59 | 60 | // GET MENU AND BUILD MOBILE NAV 61 | if(menu){ 62 | if($.isArray(menu)){ 63 | $(menu).each(function(i, e){ 64 | mobile_menu.append($(e).clone().addClass(_this.config.menu_id+"-"+i)); 65 | $(e).hide(); 66 | }); 67 | } else { 68 | mobile_menu.append($(menu).clone().addClass(_this.config.menu_id+"-0").removeAttr("id")); 69 | $(menu).hide(); 70 | } 71 | } else { 72 | return false; 73 | } 74 | }, 75 | 76 | /* 77 | * Set CSS for new layout. 78 | * 79 | * @return void 80 | */ 81 | setCSS: function(){ 82 | var _this = this; 83 | _this.config = $.extend({}, _this.defaults, _this.options); 84 | 85 | $("#build-menu-overlay").css({ 86 | position: "absolute", 87 | top: 0, 88 | bottom: 0, 89 | right: 0, 90 | left: 0, 91 | "z-index": 99, 92 | background: "#fff", 93 | opacity: 0.5, 94 | display: "none" 95 | }); 96 | 97 | $("html,body").css("height","100%"); 98 | 99 | if(_this.config.menu_bar){ 100 | $(_this.config.menu_bar).css({ 101 | position: "fixed" 102 | }); 103 | } 104 | 105 | //$("