結論から言うと、has_manyの場合と同じぽい
上記のアソシエーションを使った場合に具体的にどういうフォームを作ればいいのかまとめ
環境
Rails 5.1.5
Ruby 2.3
モデルの作成
さくっと作るためにscaffold使った
http://guides.rubyonrails.org/association_basics.html#the-has-and-belongs-to-many-association
参照
$ rails g scaffold assembly name
$ rails g model part part_number
$ rails g migration create_assemblies_parts
以下にmigrationファイルを成形確認
class CreateAssembliesAndParts < ActiveRecord::Migration[5.0]
def change
create_table :assemblies do |t|
t.string :name
t.timestamps
end
create_table :parts do |t|
t.string :part_number
t.timestamps
end
create_table :assemblies_parts, id: false do |t|
t.belongs_to :assembly, index: true
t.belongs_to :part, index: true
end
end
end
$ rake db:migrate
コントローラーの作成
assemblies_controller.rb
def new
@assembly = Assembly.new
@assembly.parts.build
end
def create
@assembly = Assembly.new(assembly_params)
@assembly.parts.build(part_params)
respond_to do |format|
if @assembly.save
format.html { redirect_to @assembly, notice: 'Assembly was successfully created.' }
format.json { render :show, status: :created, location: @assembly }
else
format.html { render :new }
format.json { render json: @assembly.errors, status: :unprocessable_entity }
end
end
end
private
def assembly_params
params.require(:assembly).permit(:name)
end
def part_params
params.require(:part).permit(:part_number)
end
ネストしている構成ではないので、ストロングパラメーターは個別に記載
collection.build
で作成したものに関しては、関連IDが予め付与されるので、Part.new
で作成したものに関しては、save後に collection<<obj
として改めて関連付けすると良さそう
フォーム画面の作成
<%= form_with(model: assembly, local: true) do |form| %>
<%= form.label :name %>
<%= form.text_field :name, id: :assembly_name %>
<%= fields_for :part do |field| %>
<%= field.label :part_number %>
<%= field.text_field :part_number %>
<% end %>
<div class="actions">
<%= form.submit %>
</div>
<% end %>
よく使いそうなメソッド(has_manyと同じ)
メソッド | 解説 |
---|---|
collection<<(object, …) | 1つ以上のモデルを多対多の関連に追加 |
collection=objects | 多対多でひも付いたモデルを更新 |
collection.build(attributes = {}) | 新しいモデルを作り、多対多で関連付けるがDBは更新しない |
collection.create(attributes = {}) | 新しいモデルを作り、多対多で関連付けてDBを更新 |
最終的にこういうことがやりたい
Eventテーブル
id | 演目 | 演者 | 開催期間 |
---|---|---|---|
1 | アニー | 劇団○○ | 10/1〜10/31 |
2 | 王家に捧ぐ歌 | 宝塚歌劇団 | 8/1〜8/31 |
3 | エリザベート | 宝塚歌劇団 | 8/1〜8/31 |
4 | エリザベート | 帝劇 | 9/1〜9/31 |
Locationテーブル
id | 会場名 |
---|---|
1 | 東京宝塚大劇場 |
2 | 帝国劇場 |
3 | 赤坂ACTシアター |
演目によって複数の会場で実施するため、以下形でレコードに入れていきたい
Event-Locationテーブル
event_id | location_id |
---|---|
1 | 1 |
1 | 2 |
2 | 1 |
3 | 1 |