0

これはRuby1.9.3p194で、Rails3.2.8を使用しています

app / models / owner.rb:

class Owner < ActiveRecord::Base
  attr_accessible :name
  has_many :pets
end

app / models / pet.rb:

class Pet < ActiveRecord::Base
  attr_accessible :name, :owner
  belongs_to :owner
end

db / migrate / 20120829184126_create_owners_and_pets.rb:

class CreateOwners < ActiveRecord::Migration
  def change
    create_table :owners do |t|
      t.string :name
      t.timestamps
    end
    create_table :pets do |t|
      t.string :name
      t.integer :owner_id
      t.timestamps
    end
  end
end

さて、今何が起こるか見てください...

# rake db:migrate
# rails console
irb> shaggy = Owner.create(:name => 'Shaggy')
irb> shaggy.pets.build(:name => 'Scooby Doo')
irb> shaggy.pets.build(:name => 'Scrappy Doo')
irb> shaggy.object_id
  => 70262210740820
irb> shaggy.pets.map{|p| p.owner.object_id}
  => [70262210740820, 70262210740820]
irb> shaggy.name = 'Shaggie'
irb> shaggy.name
  => "Shaggie"
irb> shaggy.pets.map{|p| p.owner.name}
  => ["Shaggie", "Shaggie"]
irb> shaggy.save
irb> shaggy.reload
irb> shaggy.object_id
  => 70262210740820
irb> shaggy.pets.map{|p| p.owner.object_id}
  => [70262211070840, 70262211079640]
irb> shaggy.name = "Fred"
irb> shaggy.name
  => "Fred"
irb> shaggy.pets.map{|p| p.ower.name}
  => ["Shaggie", "Shaggie"]

私の質問:ペットオブジェクトが最初に構築/作成されたときだけでなく、それらがから自動ロードされたときでも、レールを取得してshaggy.petsの要素を初期化し、所有者をシャギー(正確なオブジェクト)に設定するにはどうすればよいですか?アソシエーションを介したデータベース?

ボーナスポイント:Rails2.3.5でも機能するようにします。

4

3 に答える 3

1

2.3.5のサポートを気にしない場合は、次の方がはるかに簡単です。

app / models / owner.rb:

class Owner < ActiveRecord::Base
  attr_accessible :name
  has_many :pets, :inverse_of => :owner
end

app / models / pet.rb:

class Pet < ActiveRecord::Base
  attr_accessible :name, :owner
  belongs_to :owner, :inverse_of => :pets
end
于 2013-01-16T04:27:05.120 に答える
0

クリス、

あなたが欠けているのはこれです。

  • データベースにクエリを実行すると、その瞬間のデータのスナップショットが作成されます。
  • アソシエーションはオブジェクト参照を指していません。データベースから照会されたオブジェクトの浅いコピーです。
  • コードを機能させるには、オブジェクトをデータベースに保存して戻す必要があります。これにより、ペットは更新を適切にフェッチします。

また、あなたがしていることに間違った方向を向いていることがはっきりとわかるので、より多くのコードを表示します。

表示しているのは、Webアプリケーション用に設計されたパターンを使用したデスクトップアプリケーションパターンの例です。

于 2012-08-30T05:01:58.010 に答える
0

理解した。これは、Rails3.2.8およびRails2.3.5で機能します。

class Owner < ActiveRecord::Base
  attr_accessible :name
  has_many :pets do
    def load_target
      super.map do |pet|
        pet.owner = (proxy_association.owner rescue proxy_owner)
        pet
      end
    end
  end
end

Rails 2.3.5では、object_idshaggy.pets.map{|p| p.owner}は異なるProxyAssociationオブジェクトであるため、まだ異なりますが、少なくとも同じ基になるオブジェクトを指していることに注意してください。

これを頻繁に行う場合は、一般化することをお勧めします...

lib / Remember_parent_extension.rb:

class RememberParentExtension < Module
  def initialize(parent_name)
    parent_setter = "#{parent_name}="
    super() do
      define_method(:load_target) do
        super.map do |child|
          parent_proxy = (proxy_association.owner rescue proxy_owner)
          child.send(parent_setter, parent_proxy)
          child
        end
      end
    end
  end
end

app / models / owner.rb:

class Owner < ActiveRecord::Base
  attr_accessible :name
  has_many :pets, :extend => RememberParentExtension.new(:owner)
end
于 2012-08-30T15:15:58.530 に答える