Rails-y查询具有belongs_to关联的模型的方法

我有两个型号:

class Wine belongs_to :region end class Region has_many :wines end 

我试图使用#where方法,通过将params哈希中的某些元素转换为查询哈希来构建哈希,例如{ :region => '2452' }

 def index ... @wines = Wine.where(hash) ... end 

但是我得到的只是在执行查询时列不存在错误:

 ActiveRecord::StatementInvalid: PGError: ERROR: column wines.region does not exist LINE 1: SELECT "wines".* FROM "wines" WHERE "wines"."region" =... 

当然,表winesregion_id所以如果我查询region_id而不是我不会得到错误。

问题如下:

是否有一种rails-y方式使用#where方法中的id查询Wine对象的特定regions ? 我根据我所知道的可以做的,列出了以下一些选项。

选项1:我可以改变构建查询哈希的方式,以便每个字段都有_id (如{ :region_id => '1234', :varietal_id => '1515' }但不是Wine所有关联都是belongs_to和因此没有为_id葡萄酒的条目,使得逻辑更加复杂,加入什么不是。

选项2:构建一个SQL where子句,再次使用一些逻辑来确定是否使用id或连接另一个表…再次逻辑会稍微复杂一些,并且深入研究SQL会让它感觉更少rails-y。 或者我在那方面可能是错的。

选项3..n:我没想过的事情……你的输入就在这里:)

您可以在Wine模型中设置一个范围,使其更具轨道性…

 class Wine < ActiveRecord::Base belongs_to :region attr_accessible :name, :region_id scope :from_region, lambda { |region| joins(:region).where(:region_id => region.id) } end 

那么你可以这样做:

 region = Region.find_by_name('France') wine = Wine.from_region(region) 

编辑1:

或者如果你想真正想要你可以为多个地区做一个范围:

 scope :from_regions, lambda { |regions| joins(:region).where("region_id in (?)", regions.select(:id)) } regions = Region.where("name in (?)", ['France','Spain']) # or however you want to select them wines = Wine.from_regions(regions) 

编辑2:

如果需要,您还可以链接范围和where子句:

 regions = Region.where("name in (?)", ['France','Spain']) wines = Wine.from_regions(regions).where(:varietal_id => '1515') 

感谢所有回复的人。 我得到的答案对于单个条件查询非常有用,但我需要能够处理不同条件的东西。

我最终实现了我的选项#1,它通过迭代并将_id连接到值来构建条件哈希:

 def query_conditions_hash(conditions) conditions.inject({}) do |hash, (k,v)| k = (k.to_s + "_id").to_sym hash[k] = v.to_i hash end end 

因此该方法将采用由params构建的散列,如下所示:

 { region => '1235', varietal => '1551', product_attribute => '9' } 

并将_id拖放到每个键的末尾并将值更改为整数:

 { region_id => 1235, varietal_id => 1551, product_attribute_id => 9 } 

我们会看到这是多么可持续,但这就是我现在所用的。