関連付けしたモデルを一緒にデータ保存できる方法。
(例)propertyモデルとnearest_stationモデルが関連づいている。
*accepts_nested_attributes_forメソッドの実装に関連したコードのみ記述しています。
property.rb
class Property < ApplicationRecord
#アソシエーション設定,親モデルのデータを削除した時に子モデルも一緒に削除される。
has_many :nearest_stations, dependent: :destroy, inverse_of: :property
#reject_all_blank関数でtrueが出たパラメータは、送信データから除外させていく。
accepts_nested_attributes_for :nearest_stations, allow_destroy: true, reject_if: :all_blank
end
nearest_station.rb
class NearestStation < ApplicationRecord
belongs_to :property, inverse_of: :nearest_stations
end
properties_controller.rb
class PropertiesController < ApplicationController
before_action :set_property, only: [:show, :edit, :update, :destroy]
def index
@properties = Property.all
end
def new
#インスタンスをインスタンス変数に代入。ビューにデータを渡す
@property = Property.new
#buildメソッドを使用し、propertyモデルに属するnearest_stationモデルのインスタンスを新たに生成する。新規登録の時点で2駅保存できる
2.times { @property.nearest_stations.build }
end
def create
#paramsメソッドを使用し、送られてきたparameterを全て取得。モデルにDB操作の命令を出す。
@property = Property.new(property_params)
if @property.save
#一覧画面へ遷移して、"物件を登録しました!"とメッセージを表示する。
redirect_to properties_path, notice: "物件を登録しました!"
else
#入力フォーム(new.html.erb)を再描写
render :new
end
end
def show
@nearest_stations = @property.nearest_stations
end
def edit
@property.nearest_stations.build
end
def update
if @property.update(property_params)
redirect_to properties_path, notice: "物件を編集しました!"
else
render :edit
end
end
private
#paramsメソッドにより、parametersの値を取得。
def property_params
params.require(:property).permit(
:property_name,
:rent,
:street_address,
:age,
:note,
#attributesメソッドを使用し、インスタンスの属性(オブジェクトが持っている値)一覧を取得
nearest_stations_attributes: [
:route,
:station,
:minutes_walk,
:property_id,
:id,
:_destroy,
],
)
end
def set_property
#parameterのidを利用して、データベースからデータを取得。
@property = Property.find(params[:id])
end
end
_form.html.erb
<%= form_with(model: @property, local: true) do |form| %>
#formタグ省略
<%= form.fields_for :nearest_stations do |nearest_station| %>
<div class="route">
<%= nearest_station.label :路線名 %><br>
<%= nearest_station.text_field :route %>
</div>
<div class="station">
<%= nearest_station.label :駅名 %><br>
<%= nearest_station.text_field :station %>
</div>
<div class="minutes_walk">
<%= nearest_station.label :徒歩分数 %><br>
<%= nearest_station.text_field :minutes_walk %>分<br>
</div>
<%= form.submit '登録する' %>
<% end %>
<% end %>
show.html.erb
<% @nearest_stations.each do |nearest_station| %>
<% if @property.nearest_stations.any? %>
<%= nearest_station.route %>
<%= nearest_station.station %>
<%= nearest_station.minutes_walk %>
<% end %>