我有一些与地理相关的分类定义如下:
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。这种行为似乎与我不一致。我在网上搜索了一下,找不到任何关于这个的东西,所以我猜这是我的错误,但我不知道怎么回事。
非常感谢任何帮助。
提前致谢。
答案 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, ...>