LoginSignup
13
9

More than 3 years have passed since last update.

rails accepts_nested_attributes_for 使い方

Last updated at Posted at 2020-05-03

関連付けしたモデルを一緒にデータ保存できる方法。
(例)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 %>
13
9
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
9