読者です 読者をやめる 読者になる 読者になる

has_oneに対して、accepts_nested_attributes_forを使用する方法

rails

has_manyに対してはよくあるのに、has_oneだとないんですよね。

しかも微妙にやり方が違うっぽい(?)

実はhas_manyと同じようなやり方でできることを知っている方がいたら教えてください>_<

accepts_nested_attributes_forとは

関連するモデルに対しても、form_forで送信することができるようになります。

Imageモデルに対して、Quotationモデルが1 対 1の関係です。

app/models/image.rb

class Image < ActiveRecord::Base
  has_one :quotation

  accepts_nested_attributes_for :quotation
end

app/models/quotation.rb

class Quotation < ActiveRecord::Base
  belongs_to :image

  validates :title, presence: true
end

controllerです。

app/controllers/images.rb

  def new
    @image = Image.new
    @image.build_quotation←これでformに対して関連づけしている
  end

  def create
    @image = Image.new(image_params)←上と同じ形にしなくても大丈夫(逆にわからなかった・・・)
    if @image.save
      redirect_to @image, notice: 'image was successfully created.'
    else
      render :new
    end
  end

  private

  def image_params
    params.require(:image).permit(quotation_attributes: :title)←ここがattributesになる。詳しくはparamsの値を見てください。
  end

view側です。

= form_for @image do |f|
  - if @image.errors.any?
    #error_explanation
      h2 = "#{pluralize(@image.errors.count, "error")} prohibited this image from being saved:"
      ul
        - @image.errors.full_messages.each do |message|
          li = message

  .field
    = f.fields_for :quotation do |q|
      = q.label :title
      = q.text_field :title
    .actions = f.submit

こんな感じですね。

Image.new(image_params)で全て保存するのにびっくりしました。

これをやるためにモデル側でaccepts_nested_attributes_forを宣言してるんですかね。

ちなみにhas_manyだとnewの動きが少し変わります。

まとめてみないといけないな。