我希望我在这里做错了,有人可以指出我正确的方向......
我在我的一个模型中编写了一个方法,这里是代码:
def self.find_by_user_id(user_id, *args)
self.find(:all, :joins => :case_map,
:conditions => ['case_maps.uer_id = ? and case_maps.case_id = cases.id', user_id],
*args)
end
我可以像这样调用代码,它按预期工作:
Case.find_by_user_id(some_user_id)
但是,当使用任何其他参数执行此代码时,如下所示:
Case.find_by_user_id(some_user_id, :limit => 15)
我找回所有案件。我的日志文件中的查询显示它执行了这个:
Case Load (0.6ms) SELECT * FROM `cases` LIMIT 15
我甚至在该方法中放入了一条logger.info消息,以确保它是正在执行的消息......似乎每当* args不是nil时,它会跳过我添加到查找中的所有条件和连接并且只使用* args。
有人看到我做错的事吗?
答案 0 :(得分:3)
AR :: B#find需要可变数量的参数,但那些 last 应该是选项哈希。它使用Array#extract_options!
,您也可以:
def self.find_by_user_id(user_id, *args)
options = args.extract_options!
options.merge!(:joins => :case_map, :conditions =>
['case_maps.uer_id = ? and case_maps.case_id = cases.id', user_id])
self.find(:all, *args, options)
end
但你不应该。在:all和options字段之间有哪些可能的值有意义?
你真正追求的是:
def self.find_by_user_id(user_id, options)
self.find(:all, options.merge(:joins => :case_map, :conditions =>
['case_maps.user_id = ? and case_maps.case_id = cases.id', user_id]))
end
或者更好一点:
named_scope :find_by_user_id, lambda{|user_id|
{
:joins => :case_map,
:conditions => ['case_maps.user_id = ? and case_maps.case_id = cases.id', user_id]
}
}
命名范围将确保所有选项都干净地合并(即使您稍后添加更多条件,也会应用所有条件)。然后你可以用:
来调用它Case.find_by_user_id(user_id).all(:limit => 15)
(命名范围是“Da Bom”。应该尽可能多地使用它们。即使在一般的谈话中。例如,如果你昨晚在我家里,你可能会听到这个小曲子:“做什么你想要你的晚餐吗?“,”我每晚都有同样的事情,命名范围和芯片。“。因为我承诺所有这一切。)
另外,作为附注,假设这是在你的Case模型上,“and case_maps.case_id = cases.id
”子句是不必要的,:joins => :case_map
为你做这件事。