fields_forの使い方をマスターしよう
※本記事は子モデルの画像を編集する場合を想定しています。
誰のための記事か
・fields_forの使い方がわからない
・新規登録はできるがレコードの更新ができない
そもそもfields_forとは
form_for内で異なるモデルを編集できるようになる。
fields_forを使うことによって異なるモデル(子モデル)を編集できるようになる。
例:Articleモデルに紐付くImageモデル
newで使う
フォーム
_form.html.erb
<%= form_for @article do |f| %>
<%= f.text.field :title %>
<%= f.fields_for :images do |image| %>
<%= image_tag(image.object.content) %> #画像があれば表示する
<%= image.file_field :content %>
<%= image.hidden_field :id, value: image.object.id %> #編集時にはidが必要らしい
<%= f.submit %>
<% end %>
コントローラ
articles_controller.rb
def new
@article = Article.new
@article.images.build
end
def create
@article = current_user.articles.build(article_params)
@article.save
end
def article_params
params.require(:article).permit(:title, images_attributes: [:content])
end
モデル
article.rb
has_many :images
accepts_nested_attributes_for :images
image.rb
belongs_to :article
mount_uploader :image, ImageUploader
これで画像を子モデルに保存することができます。
editで使う
フォーム
_form.html.erb
#フォームはnewと同じです
<%= form_for @article do |f| %>
<%= f.text.field :title %>
<%= f.fields_for :images do |image| %>
<%= image_tag(image.object.content) %> #画像があれば表示する
<%= image.file_field :content %>
<%= image.hidden_field :id, value: image.object.id %> #編集時にはidが必要らしい
<%= f.submit %>
<% end %>
コントローラ
articles_controller.rb
def edit
@article = Article.find(params[:id])
end
def update
@article.update(update_article_params)
end
def update_article_params
#update時は[_delete]と[id]が必要
params.require(:article).permit(:title, images_attributes: [:content, :_destroy, :id])
end
モデル
article.rb
#もちろんモデルもnewと同じ
has_many :images
accepts_nested_attributes_for :images
image.rb
#もちろんモデルもnewと同じ
belongs_to :article
mount_uploader :image, ImageUploader
これだけで画像の更新ができてしまいます。
##最後に
fields_forの使い方は意外と難しく、記事もあまり数がありません。
少しでも皆様のお役に立てば幸いです。