使用ActiveRecord将条件置于多对多查询中

时间:2009-12-10 23:39:09

标签: sql ruby-on-rails ruby activerecord

我的模型中有以下关系:

class Show < ActiveRecord::Base
  has_many :service_shows
  has_many :services, :through => :service_shows
end

class Service < ActiveRecord::Base
  has_many :service_shows
  has_many :shows, :through => :service_shows
end

class ServiceShow < ActiveRecord::Base
  belongs_to :show
  belongs_to :service
end

我想查询具有rec_status ='A'的给定服务的所有节目,但我的ActiveRecord技能只有三天左右,所以我不太满意。如果我理解正确,我可以简单地调用service.shows并过滤返回的列表,但我只想从数据库中检索我需要的记录 - 我宁愿不把处理器时间和内存浪费在我不记录的记录上我想要。

谢谢!

1 个答案:

答案 0 :(得分:6)

根据您的描述,它听起来像是:rec_status列。基于此,我设置了一些示例数据:

Show.create!(:name => 'One', :rec_status => 'A')
Show.create!(:name => 'Two', :rec_status => 'B')

Service.create!(:name => 'Service One')
Service.create!(:name => 'Service Two')

Show.first.services = Service.all
Show.last.services = Service.all

如您所说,只要提供一项服务,您就可以取回所有节目:

service = Service.first
service.shows

如果要选择记录子集,可以使用finder调用扩展链:

service.shows.all(:conditions => {:rec_status => 'A'})

更好的是,您可以在Show模型中将其捕获为命名范围:

class Show < ActiveRecord::Base
  has_many :service_shows
  has_many :services, :through => :service_shows

  named_scope :for_status, lambda {|status_flag| {:conditions => {:rec_status => status_flag}} }
end

然后使用它而不是传递:conditions哈希:

service.shows.for_status('A')