3

この質問を説明するのは難しいので、それが私が思いつくことができる最高のタイトルなので、ここにいくつかのコードがあります.

親、子、孫の 3 つのモデルが与えられます。

Parent <  ActiveRecord::Base
  has_many :children
  has_many :grandchildren
  accepts_nested_attributes_for :child
end

Child <  ActiveRecord::Base
  belongs_to :parent
  has_many :kids, :as => :grandchildren #this is just an example
  accepts_nested_attributes_for :grandchild
end

Grandchild <  ActiveRecord::Base
  belongs_to :parent
  belongs_to :child
end

Parent#new で作成される子レコードと孫レコードの両方に current_user.id を追加したいと思います。隠しフィールドを追加する良い方法が見つからなかったため、今のところ隠しフィールドを使用しています。

作成時に current_user.id を追加するコールバックを作成することで、誰かが助けてくれるでしょうか? とにかく、それをモデルに入れることはあまり運がありませんでしたが、あなたは頭がいいです。

考え?

4

2 に答える 2

5

一つには、has_many :through親から孫へ (子を介して)、またはその逆の関係をお勧めします。詳細については、ActiveRecord アソシエーション クラス メソッド APIの「アソシエーション ジョイン モデル」セクションを参照してください。

あなたの主な質問に関しては、あなたが言うように、おそらくコールバックが必要です。私はこのようなことをすべきだと思います(これはテストされていないコードですが):

class Parent
  # ...somewhere at the top...
  before_create :set_current_user_on_descendants

  # ...somewhere in the main class body...
  # (I assume parent['current_user'] is passed in as a typical 
  # parameter, and thus self.current_user is already set.)
  def set_current_user_on_descendants
    children.each { |c| c.current_user = self.current_user }
    grandchildren.each { |gc| gc.current_user = self.current_user }
  end
end

別の方法で行うことができるスタイル上のポイントがいくつかあります。たとえば、子と孫を返す「子孫」メソッドを定義して、それを反復するか、子クラスと孫クラスにコールバックを実装することができます (この場合、最大のモジュールにそれを引き出すことができます)。 DRYness、ただし、2 つのクラスのみの 1 行のメソッドの場合はやり過ぎになる可能性があります)。current_user をいつ更新したいかによっては、before_saveまたは代わりに他のコールバックを使用したい場合があります - ActiveRecord コールバック APIbefore_createで利用可能なコールバックの完全なリストを見つけることができます。

于 2009-12-29T19:06:49.793 に答える
0

save!デフォルトのメソッドをオーバーライドすることも可能だと思います

class Parent < ActiveRecord::Base
   def save! 
      children.each { |c| c.current_user = @current_user }
      grandchildren.each { |gc| gc.current_user = @current_user }

      super
   end
end

こちらも未検証。これが機能するかどうかは本当にわかりません...

于 2009-12-29T21:52:17.853 に答える