繁体   English   中英

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

[英]Rails-y way to query a model with a belongs_to association

我有两个型号:

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而不是错误。

问题如下:

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

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

选项2:构建一个SQL where子句,再次使用一些逻辑来确定是否对另一个表使用id或join ...再次逻辑会更复杂一些,并且深入研究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 }

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM