简体   繁体   English

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

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

I have two models: 我有两个型号:

class Wine
  belongs_to :region
end

class Region
  has_many :wines
end

I am attempting to use the #where method with a hash built from transforming certain elements from the params hash into a query hash, for example { :region => '2452' } 我试图使用#where方法,通过将params哈希中的某些元素转换为查询哈希来构建哈希,例如{ :region => '2452' }

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

But all I get is a column doesn't exist error when the query is executed: 但是我得到的只是在执行查询时列不存在错误:

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

Of course, the table wines has region_id so if I queried for region_id instead I would not get an error. 当然, winesregion_id所以如果我查询region_id而不是错误。

The question is the following: 问题如下:

Is there a rails-y way to query the Wine object for specific regions using the id in the #where method? 是否有使用#where方法中的id查询Wine对象的特定regions的rails-y方法? I've listed some options below based on what I know I can do. 根据我所知道的,我列出了以下一些选项。

Option 1: I could change the way that I build the query hash so that each field has _id (like { :region_id => '1234', :varietal_id => '1515' } but not all of the associations from Wine are belongs_to and thus don't have an entry in wines for _id , making the logic more complicated with joins and what not. 选项1:我可以改变构建查询哈希的方式,以便每个字段都有_id (如{ :region_id => '1234', :varietal_id => '1515' }但不是Wine所有关联都是belongs_to和因此没有为_id葡萄酒的条目,使得逻辑更加复杂的连接和什么不是。

Option 2: Build a SQL where clause, again using some logic to determine whether to use the id or join against another table... again the logic would be somewhat more complicated, and delving in to SQL makes it feel less rails-y. 选项2:构建一个SQL where子句,再次使用一些逻辑来确定是否对另一个表使用id或join ...再次逻辑会更复杂一些,并且深入研究SQL会让它感觉更少rails-y。 Or I could be wrong on that front. 或者我在那方面可能是错的。

Option(s) 3..n: Things I haven't thought about... your input goes here :) 选项3..n:我没想过的事情......你的输入就在这里:)

You could set up a scope in the Wine model to make it more rails-y ... 您可以在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

So then you can do something like: 那么你可以这样做:

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

Edit 1: 编辑1:

or if you want to be really fancy you could do a scope for multiple regions: 或者如果你想真正想要你可以为多个地区做一个范围:

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) 

Edit 2: 编辑2:

You can also chain scopes and where clauses, if required: 如果需要,您还可以链接范围和where子句:

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

Thanks to all who replied. 感谢所有回复的人。 The answers I got would be great for single condition queries but I needed something that could deal with a varying number of conditions. 我得到的答案对于单个条件查询非常有用,但我需要能够处理不同条件的东西。

I ended up implementing my option #1, which was to build a condition hash by iterating through and concatenating _id to the values: 我最终实现了我的选项#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

So that the method would take a hash that was built from params like this: 所以该方法将采用由params构建的散列,如下所示:

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

and drop an _id onto the end of each key and change the value to an integer: 并将_id放到每个键的末尾,并将值更改为整数:

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

We'll see how sustainable this is, but this is what I went with for now. 我们会看到这是多么可持续,但这就是我现在所用的。

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

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