#やろうとしていること
多対多のテーブル構造を構築し、viewからparameterを送り、workとworkplaceに保存したい。
(placeのレコードはseedで作っているので、新規追加はしません。)
E-R図はこんな感じです。この会社が募集している仕事は、どの地域にあるのかをわかるようにしたい。
workテーブルとplaceテーブルの中間として、work_placeテーブルを作りました。
#コード
##モデル:
#work.rb
has_many :work_places, dependent: :destroy
has_many :places, :through => :work_places
accepts_nested_attributes_for :work_places, allow_destroy: true
#place.rb
has_many :work_places, dependent: :destroy
has_many :works, :through => :work_places
#work_place.rb
belongs_to :work
belongs_to :place
accepts_nested_attributes_forがキモ。上の例だと、workモデルに新しいレコードが保存された際に、そのwork_idとplace_idがwork_placeに保存されるようにする。中間テーブルを通りますよってことで、workモデルとplaceモデルに:throughを追加。
##コントローラー:
def new
@work = Work.new
@work.work_places.build
end
def create
@work = Work.new(work_params)
end
def work_params
params.require(:work).permit(:company)
end
ここではbuildが重要。workレコードが保存された際に、work_placeレコードにも保存をかけますよってことを指示する。
##ビュー:
<%= form_for @work do |f| %>
<%= f.label :company, "会社名" %>
<%= f.text_area :company %>
<%= f.fields_for :work_places do |ff| %>
<%= ff.label :placename, "渋谷" %>
<%= ff.check_box :place_id,{}, 1,"渋谷",nil%>
<%= ff.label :placename, "新宿" %>
<%= ff.check_box :place_id,{}, 2,"新宿",nil %>
<%= ff.label :placename, "池袋" %>
<%= ff.check_box :place_id,{}, 3,"池袋",nil %>
<%= f.submit "投稿" %>
<% end %>
#これでいけるかと思いきや。。。。(問題発生)
というわけでこれで保存できると思ったんですが、
work_placeモデルにplace_idが保存されない!
work_placeがunpermittedになっている。
insert work_placeは走って、work_idは保存されるのに〜!
#解決策はstrongparameterにありました!
なんと、accepts_nested_attributes_forを使うときは、strongparameterもいじらなければならないようです。
def new
@work = Work.new
@work.work_places.build
end
def create
@work = Work.new(work_params)
end
def work_params
params.require(:work).permit(:company, work_places_attributes:[:id,:place_id])
end
このように、関連させているモデル名(これはhasmanyしているのでsがついてwork_placesです)にattributesをつけて、カラムを追記してあげなければなりません。
すると。。。。
place_idも保存されました!
単に、モデルにaccepts_nested_attributes_forをつければいいのかと。。。。
#まとめると。。。。
モデル=>accepts_nested_attributes_forを入れましょう
コントローラー=>newメソッドの中にbuildを入れ、strongparameterにattributesをつけましょう(ここ大事!)
ビュー=>fields_forで関連付け
##個人開発をされている方へ
Moverというプロダクトを開発しています。登録していただくと、開発したプロダクトのテスト利用を依頼し、フィードバックをもらうことができます。自分のプロダクトを公開して個人開発を加速させましょう!! 現在僕のアカウントも登録されているので、そちらにテスト利用依頼をいただければ実際に使ってみた感想などをお送りさせて頂きます。(アドバイスなどではなく、一人のユーザーとしての感想となります。) もちろん無料です。
https://mover-web.herokuapp.com/