【问题标题】:Rails-y way to query a model with a belongs_to associationRails-y 查询具有 belongs_to 关联的模型的方法
【发布时间】:2012-11-29 05:40:50
【问题描述】:

我有两个模型:

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?我根据自己的能力在下面列出了一些选项。

选项 1: 我可以更改构建查询哈希的方式,以便每个字段都有_id(例如{ :region_id => '1234', :varietal_id => '1515' },但并非来自Wine 的所有关联都是belongs_to,因此在wines 中没有@ 的条目987654336@,使逻辑更复杂的连接等等。

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

选项 3..n: 我没有想到的事情......你的意见在这里:)

【问题讨论】:

  • 任一答案是否有助于您解决问题?

标签: ruby-on-rails activerecord belongs-to


【解决方案1】:

您可以在 Wine 模型中设置一个范围,使其更符合 Rails-y ...

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')

【讨论】:

  • 刚刚提供了一个如何组合范围和 where 子句的示例。
【解决方案2】:

感谢所有回复的人。我得到的答案非常适合单一条件查询,但我需要一些可以处理不同数量条件的东西。

我最终实现了我的选项 #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

因此该方法将采用这样的参数构建的哈希:

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

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

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

我们将看看这是多么可持续,但这是我目前所采用的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多