我有一组与地理相关的类:State,Msa,County,City等。这些类都来自基本的Location类。这些类在很大程度上通过称为地理的非规范化连接表相关。所以我有......
class Geography < ActiveRecord::Base
belongs_to :state
belongs_to :county
belongs_to :city
# ... etc.
end
class Location < ActiveRecord::Base
end
class State < Location
has_many :geographies
has_many :msas, :through => :geographies, :uniq => true
# ... etc.
end
class Msa < Location
has_many :geographies
has_many :states, :through => :geographies, :uniq => true
# ... etc.
end
现在,当我从控制台运行以下命令时:
>> msas = Msa.find(:all, :include=>"states", :conditions=>{"states_locations"=>{"id"=>"1"}})
我找回了正确数量的结果(在这种情况下为13)。但是,运行此查找调用生成的SQL会得到1,000个结果(同样地理表是各种类型的数据集合,这就是我在关联时使用:uniq选项的原因)。
SELECT `locations`.`id` AS t0_r0,
`locations`.`parent_id` AS t0_r1,
`locations`.`type` AS t0_r2,
`locations`.`name` AS t0_r3,
`states_locations`.`id` AS t1_r0,
`states_locations`.`parent_id` AS t1_r1,
`states_locations`.`type` AS t1_r2,
`states_locations`.`name` AS t1_r3
FROM `locations`
LEFT OUTER JOIN `geography`
ON `locations`.`id` = `geography`.`msa_id`
LEFT OUTER JOIN `locations` states_locations
ON `states_locations`.`id` = `geography`.`state_id`
AND `states_locations`.`type` = 'State'
WHERE `states_locations`.`id` = '1'
AND `locations`.`type` = 'Msa'
我认为这意味着Rails将1000条记录加载到内存中,然后在Ruby中将结果减少到不同的Msas集合(在这种情况下);似乎有点低效。此外,以下后续调用会返回不同的结果:
>> msas.first.states.size # incorrect count
=> 192
>> msas.first.states.count # correct count
=> 1
>> msas.first.states # incorrect number of State objects
=> [#<State id: 1, ... >, ..., #<State id: 1, ... >]
>> msas.first.reload.states
=> [#<State id: 1, ... >] # correct number of State objects
我的问题是:
非常感谢任何见解。
提前致谢, 杰森
答案 0 :(得分:1)
那里有很多问题,让我看看这是否会有所帮助......
你是正确的,rails会触发一个sql调用来获取所有结果,然后active_record应该过滤掉唯一记录。
如果您想避免这样做,您可以执行以下操作:
has_many :states, :through => :geographies, :select => "DISTINCT states.*"
这个post有趣的分析
还有你的专栏:
msas = Msa.find(:all, :include=>"states", :conditions=>{"states_locations"=>{"id"=>"1"}})
它没有返回唯一结果,因为您没有利用您设置的关系。你可能想做类似的事情:
@msas = State.find(state_id).msas