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

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

新規登録して質問してみよう
ただいま回答率
85.50%
Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Q&A

解決済

1回答

1336閲覧

複数の親子孫モデルをまとめて更新したい

niki

総合スコア7

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

0グッド

0クリップ

投稿2018/06/09 02:10

前提・実現したいこと

親、子、孫と3つの関連テーブルがあり、親と子は1:1、子と孫は1:nの状態です。
親をwhere句で検索した後、検索結果の親に関連する子と孫の値を更新したいです。

Ruby

1#親モデルのリレーション 2has_one :child, dependent: :destroy, inverse_of: :parent 3accepts_nested_attributes_for :child 4 5#子モデルのリレーション 6belongs_to :parent, inverse_of: :child 7accepts_nested_attributes_for :child_members 8 9#孫モデルのリレーション 10belongs_to :child, inverse_of: :child_members

Ruby

1#更新するコード※controllerに記述 2p = Parent.where(id: params[:id]) 3p.colA = 0 4p.child.colB = 10 5p.child.child_members.colC = 20 6p.save

※params[:id]は、Viewから渡されるidの配列で、ここに値が入っていて、SQLが実行されてデータが取れていることは確認しています
※colA,colB,colCは、それぞれのモデルにあるカラムで、更新時には画面から渡される値ではない値を入れたい

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

NoMethodError: undefined method `child' for nil:NilClass

該当のソースコード

Ruby

1p.child.colB = 10

試したこと

・親モデルを検索するときにfindを使うと、p.child.colBは取れますが、p.child.child_membersはNoMethodErrorになります

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

まず、childモデルにhas_many :child_membersが抜けています。

あとはそれが複数なのか単数なのかを意識してみましょう。

ruby

1p = Parent.where(id: params[:id]) 2p.colA = 0 3p.child.colB = 10 4p.child.child_members.colC = 20 5p.save

1行目ですが、whereはActiveRecord_Relationで返ってきます。簡単に言うと配列みたいな形です。
findと同じように使うなら.firstをつけましょう。

4行目ですが、child_membersは複数ですので、一括でcolCを20にするというのはできません。

ruby

1p.child.child_members.each do |m| 2 m.colC = 20 3end

このように1つ1つ処理してやりましょう。

投稿2018/06/12 07:29

chelsy7110

総合スコア596

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

niki

2018/06/12 09:41

ご回答をありがとうございます! 一括では行えず、一つ一つループする方法になるのですね。 それですと、ループの回数文、UPDATE文が発行されることになり、場合によっては負荷がかかるかもしれません。 運用を考え、教えていただいた方法で行うか、SQLを直で書くか考えたいと思います。 ありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問