命名范围/过滤器问题

时间:2011-08-03 16:29:05

标签: ruby-on-rails ruby scope named

抱歉,Ruby on Rails我仍然有点绿色,至少可以说,所以即使被引导到同一个方向,我也会感激。

所以......我有三个数据库表,让我们称之为人,工作和帽子。 我的范围只返回做某些工作的人:

named_scope :emergency_workers, :include => :job, :conditions => {'jobs.name' => 'Police', 'jobs.name' => 'Fire','jobs.name' => 'paramedic'}

我有一个范围,只返回戴帽子的人:

named_scope :hat_wearers, :include => :job, :joins => :hat, :conditions => ["hats.name IS NOT ?", nil]

我的问题是,我如何定义一个范围,说“只告诉我戴帽子的人(如上所述),除非他们做这个特殊的工作,”农民说。所以,我的代码将归还所有帽子佩戴者和所有农民。

不确定这是否会让人感觉到舔,但我会非常感谢指导...

2 个答案:

答案 0 :(得分:2)

我不确定如何将其构造为单个查询,但是使用Rails 3语法可以指定给定的范围,然后创建一个方法,从两个范围的查找中返回唯一结果:

class People < ActiveRecord::Base
  ...
  scope :emergency_workers, joins(:jobs).where('jobs.name IN (?)',['Police','Fire','Paramedic'])
  scope :hat_wearers, joins(:hats).where('hats.name IS NOT ?', nil)
  scope :farmers, joins(:jobs).where('jobs.name= ?', 'farmer')
  ...

  def hats_and_farmers
    result = self.class.hat_wearers + self.class.farmers
    result.uniq
  end
  ...
end

修改

我不知道如何编写SQL来基于三个表进行查找,但如果你这样做(根据你的评论),只需写下:

People.find_by_sql('Your custom from scratch query goes here.')

请参阅:http://guides.rubyonrails.org/active_record_querying.html#finding-by-sql

所有从模型中调用它的方法都是告诉Rails你期望查询返回什么样的对象,以便它可以将它们实例化为可供你使用的对象。没有为您预先编写SQL。

答案 1 :(得分:0)

我建议使用两个单独的命名范围并将它们链接在一起。您可以使用现有的hat_wearers范围,还可以定义一个范围,该范围包含要排除的作业名称:

named_scope :hat_wearers, :joins => :hat, :conditions => ["hats.name IS NOT ?", nil]
named_scope :without_worker, lambda{|j| :joins  => :job, :conditions => ['jobs.name != ?', j]}

现在,您可以将它们链接在一起并调用person.hat_wearers.without_worker('farmer')以及单独使用范围。

警告提示:根据您使用的Rails版本,链接范围:连接可能会变得棘手。有几个人在网上写过关于它的文章并在这个网站上询问过,所以如果你遇到问题就检查一下。