質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.78%

Rails5 form_withとfields_forを使った、複数モデルの更新ができない。

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 1,905

yamaoka_san

score 22

前提・実現したいこと

親モデルの入力フォームから子モデルのカラムを更新したい。

発生している問題・エラーメッセージ

エラーメッセージは出ないです。子モデルが更新されないだけです。

親モデル(1):frame、 子モデル(複数):img
1対nの関係

[frame.rb]
#association
has_many :imgs
accepts_nested_attributes_for :imgs

[img.rb]
#association
belongs_to :frame, optional: true
[frames_controller.rb]
def edit
@frame = Frame.find(params[:id])
end

def update
@frame = Frame.find(params[:id])
@frame.update(frame_update_params)
end

private
def frame_update_params
    params.require(:frame).permit(:page1, imgs_attributes: [:img_in_order, :id])
end
[frames/1/edit.html.erb]
<%= form_with(model: @frame, local: true) do |m| %>
<%= m.hidden_field :page1, :value => '1' %>
<%= m.fields_for :img do |e| %>
<%= e.hidden_field :img_in_order, :value => '1', :name =>'img[img_in_order]', :id =>'img_img_in_order' %>
<% end %>
<%= m.submit "更新" %>
<% end %>

試したこと

Railsフォームのnested_attributesを使って、デフォルト値の異なる複数の関連レコードを作成する方法
Rails5.1からのform_withでnested_formを扱う方法
fields_forの上手な使い方
Active Record Nested Attributes
この記事を主に参考にしながら考えました。

CarrierWaveは使わず、imgモデルはimgの方でcreateできるようになっています。
imgのimg_in_orderカラムに値を入れたいだけです。

<%= m.hidden_field :page1, :value => '1' %>

page1は動きます。

<%= e.hidden_field :img_in_order, :value => '1', :name =>'img[img_in_order]', :id =>'img_img_in_order' %>


img_in_orderは全く値が入りません。
本当に欲しいのは:value=>'1'だけなのですが、fields_forで親モデル(frame)と子モデル(img)を紐づけてしまうと、:idや:nameにおかしな値が勝手に入ってしまうので、正しく更新されているframeモデルの方を参考に入れています。
(この値があっても、取ってしまっても、imgの更新はできませんが)

試した事:
binding.pryだと入力フォーム直後でもimgの値が入っていないようです。
紐付けが上手くいっていないのか、fields_forの書き方がダメなのか、気づく部分は直してこの状態です。

補足情報(FW/ツールのバージョンなど)

ruby 2.5.1p57 (2018-03-29 revision 63029) [x86_64-linux]
Rails 5.2.2

今のところは以上です。何か進展があれば、コレ以降に加筆していきます。
どうぞよろしくお願いします。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

0

  1. @frame.update(frame_update_params) を @frame.update!(frame_update_params) に変更してエラーが見えるようにする
  2. @frame.imgs が空ではないことを確認する
  3. fields_for :img の部分を次のように変更する
 <% @frame.imgs.each do |img| %>
   <%= m.fields_for(:imgs, img) do |e| %>
     <%= e.hidden_field :img_in_order, :value => '1' %>
   <% end %>
 <% end %>

4 次のようにリレーションの定義を変更

# frame.rb
has_many :imgs, inverse_of: :frame
accepts_nested_attributes_for :imgs

# img.rb
belongs_to :frame

以上を順番に試してみてください。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/04/17 12:15

    回答いただき、ありがとうございます!
    早速トライしていますが、調べる事モノがどっさりなので、取り急ぎお礼だけさせてください。

    今は1番のupdate!で、エラー(と言うかフォームから引き渡されている値)を確認しています。

    キャンセル

  • 2019/04/17 14:11

    正確に言うと、私が考えている方法だと、accepts_nested_attributes_forが使えない。と言うことが分かりました。
    accepts_nested_attributes_for :imgsはnewアクションで
    def new
    @親モデル = 親モデル.new
    @親モデル.子モデルs.build
    end
    によってしか紐付けされないようです
    (https://qiita.com/tomoharutsutsumi/items/761bdb114883f12edcd2)

    しかし私の考えていた入力フォームだと、newアクションが別にある為、きちんと紐付けされていなかったことが原因だと思います。

    お手数をおかけしました。できなくてとてもとても残念ですが、違う方法を考えます。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.78%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る