装?始终对belongs_to关联返回true?

时间:2010-01-22 22:41:56

标签: ruby-on-rails

我有一些与地理相关的分类定义如下:

class Location < ActiveRecord::Base
end

class State < Location
  has_many :geographies
  has_many :cities
  has_many :counties
end

class County < Location
  belongs_to :state
  has_many :geographies
  has_many :cities, :through => :geographies, :uniq => true
end    

class City < Location
  belongs_to :state
  has_many :geographies
  has_many :counties, :through => :geographies, :uniq => true
end

class Geography < ActiveRecord::Base
  belongs_to :state
  belongs_to :city
  belongs_to :county
end

以下控制台输出演示了我遇到的问题。

>> County.first.cities.loaded?
=> false
>> County.first.state.loaded?
=> true

查看日志,我看到当我调用state.loaded时?它运行一个SQL语句来加载状态,即直到我“触摸”状态才加载状态。但是,当我调用cities.loaded?没有执行SQL并返回false。这种行为似乎与我不一致。我在网上搜索了一下,找不到任何关于这个的东西,所以我猜这是我的错误,但我不知道怎么回事。

非常感谢任何帮助。

提前致谢。

2 个答案:

答案 0 :(得分:1)

我认为这取决于所使用的关系类型以及与延迟加载的交互。

当您调用 County.first.state 时,Rails将加载属于County的状态对象 - 只有一个,因此对.state的调用实际上是对''的调用'数据库中可以加载的具体'对象。

但是,当您调用 County.first.cities 时,实际上是在调用属于county对象的关系集合。由于您实际上没有调用特定对象或一组条件,因此Rails足够聪明,无法加载集合。

如果你说的话:

County.first.cities.all
County.first.cities.each
County.first.cities.first

然后Rails将启动SQL语句并加载数据。

答案 1 :(得分:0)

我发现您可以使用Object方法instance_variable_get来检查是否加载了belongs_to关联,而不会触发在检查期间加载的关联。所以......

>> c = County.first
=> #<County id: 1, ...>
>> c.instance_variable_get("@state")
=> nil
>> c.state
=> #<State id: 1, ...>
>> c.instance_variable_get("@state")
=> #<State id: 1, ...>
>> c = County.first(:include => :state)
=> #<County id: 1, ...>
>> c.instance_variable_get("@state")
=> #<State id: 1, ...>