0

has_one 関連付けメソッドの実行に一貫性がなく、その理由がわかりません。

互いに関連付けられている 2 つの単純なモデルを取り上げます。

class Container < ActiveRecord::Base
  has_one: :super
end

class Super < ActiveRecord::Base
  belongs_to: :container
end

次のコードは正常に機能します。

container = Container.create
 ...

container.build_super
 ...
 => #<Super id: nil, container_id: 1, content: nil, created_at: nil, updated_at: nil>

container.super
 => #<Super id: nil, container_id: 1, content: nil, created_at: nil, updated_at: nil>

上記のコードで container.super を呼び出すと、クラス Super の新しく構築されたインスタンスが返されます。

ただし、次のコードは機能しません。

Container.create
 ...
 => #<Container id: 1, created_at: "2013-10-26 20:31:26", updated_at: "2013-10-26 20:31:26">

Container.first.build_super
 ...
 => #<Super id: nil, container_id: 1, content: nil, created_at: nil, updated_at: nil>

Container.first.super
  Container Load (0.2ms)  SELECT "containers".* FROM "containers" ORDER BY "containers"."id" ASC LIMIT 1
  Super Load (0.1ms)  SELECT "supers".* FROM "supers" WHERE "supers"."container_id" = ? ORDER BY "supers"."id" ASC LIMIT 1  [["container_id", 1]]
 => nil

Container.first.super は、データベースで Super のインスタンスを探しているように見えるため、nil を返します。ただし、インスタンスはまだコミットされていません。

しかし、container == Container.first の場合、container.super と Container.first.super で同じ結果が得られないのはなぜですか?

4

2 に答える 2

2

Container.first.build_superコンテナ レコードのコピーを取得し、関連付けインスタンスを構築して、この関連付けインスタンスをコンテナ レコードのコピーにキャッシュします。

この後に呼び出すContainer.first.superと、Container レコードの別のコピーがフェッチされ、:super.

基本的に、これを行っています:

a = Container.first    # New instance
a.build_super          # Assign to :super

b = Container.first    # Separate instance
b.super                # Nothing in :super

おそらくやりたいことは、別のコピーをフェッチする代わりに、これを変数に代入することです:

container = Container.first
container.build_super
container.super
于 2013-10-26T21:20:19.053 に答える