# はじめに
ドットインストールのRuby on Rails 4入門では、「Project」と「Task」の2つの入力画面があり、レッスン内では、Project側のみ、入力エラー時のメッセージを表示させる処理を実装しています。その後、Project側の実装を参考にTask側の実装してみたところ、ちょっとつまずいたので、そのときの備忘録です。
バージョン
% ruby -v
ruby 2.3.1p112 (2016-04-26 revision 54768) [x86_64-linux]
% rails -v
Rails 4.2.7.1
作業の流れ
task.rb 修正前
/app/models/task.rb
class Task < ActiveRecord::Base
belongs_to :project
- validates :title, presence: true
scope :unfinished, -> { where(done: false) }
end
task.rb 修正後
/app/models/task.rb
class Task < ActiveRecord::Base
belongs_to :project
+ validates :title,
+ presence: { message: "入力してください" },
+ length: { minimum: 3, message: "短すぎ!" }
scope :unfinished, -> { where(done: false) }
end
tasks_controller.rb 修正前
/app/controllers/tasks_controller.rb
class TasksController < ApplicationController
def create
@project = Project.find(params[:project_id])
- @task = @project.tasks.create(task_params)
- redirect_to project_path(@project.id)
end
tasks_controller.rb 修正後
/app/controllers/tasks_controller.rb
class TasksController < ApplicationController
def create
@project = Project.find(params[:project_id])
+ @task = @project.tasks.build(task_params)
+ if @task.save
+ redirect_to project_path(@project.id)
+ else
+ # @project.tasks.build で tasks に1行追加されている
+ # そのままだと一覧にエラーの分も表示されてしまうので再取得する
+ @project = Project.find(params[:project_id])
+ render 'projects/show'
+ end
end
show.html.erb 修正前
/app/views/projects/show.html.erb
- <%= form_for [@project, @project.tasks.build] do |f| %>
<p>
<%= f.text_field :title %>
</p>
show.html.erb 修正後
/app/views/projects/show.html.erb
+ <%# @project.tasks.build だと @task.errors にメッセージが入らないため @task に変更 %>
+ <%= form_for [@project, @task] do |f| %>
<p>
<%= f.text_field :title %>
+ <% if @task.errors.any? %>
+ <%= @task.errors.messages[:title][0] %>
+ <% end %>
</p>
projects_controller.rb 修正前
/app/controllers/projects_controller.rb
class ProjectsController < ApplicationController
def show
end
projects_controller.rb 修正後
/app/controllers/projects_controller.rb
class ProjectsController < ApplicationController
def show
+ # show.html.erb の @project.tasks.build を @task に変更したため追加
+ @task = Task.new
end
最後に
エラーメッセージを flash で ProjectsController に渡す方法も試したのですが、個人的にはこの方法がしっくりきました。
まだまだ、Rails初心者なので、他にもっとベターな方法がありましたら、教えていただけると助かります。