命名作用域/过滤器问题



对不起,至少可以说我对Ruby on Rails还不太熟悉,所以我很感激即使是在相同的方向上被引导。

所以…我有三个数据库表,分别叫它们people, jobs和hats。我有一个范围,它只返回做某些工作的人:

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]

我的问题是,我如何定义一个范围,说"只显示给我戴着帽子的人(如上所述),除非他们做这个特定的工作,比如农民"。因此,我的代码将返回所有戴帽子者和所有农民。

不确定这是否有意义,但我非常感谢您的指导…

我不确定如何将其构建为单个查询,但使用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你期望查询返回什么样的对象,这样它就可以将它们实例化为对象供你使用。

我建议使用两个单独的命名作用域并将它们链接在一起。您可以使用现有的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版本的不同,用:join链接作用域可能会变得很棘手。有几个人在网上写过这个问题,也在这个网站上问过这个问题,所以如果你遇到了问题,可以去看看。

最新更新