当附加args时,Rails find将不会加入

时间:2009-08-31 19:17:54

标签: ruby-on-rails find join

我希望我在这里做错了,有人可以指出我正确的方向......

我在我的一个模型中编写了一个方法,这里是代码:

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。

有人看到我做错的事吗?

1 个答案:

答案 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为你做这件事。