0

我正在实施我的第一个 HABTM 关系并且遇到了我的查询问题。

我正在寻找验证我的方法并查看是否在 AREL(或 Rails 的其他部分)代码中发现了错误。

我有以下型号

class Item < ActiveRecord::Base
  belongs_to :user
  belongs_to :category
  has_and_belongs_to_many :regions
end

class Region < ActiveRecord::Base
  has_ancestry
  has_and_belongs_to_many :items
end

我有关联的 items_regions 表:

class CreateItemsRegionsTable < ActiveRecord::Migration
  def self.up
    create_table :items_regions, :id => false do |t|
      t.references :item, :null => false
      t.references :region, :null => false
    end
    add_index(:items_regions, [:item_id, :region_id], :unique => true)
  end

  def self.down
    drop_table :items_regions
  end
end

我的目标是创建一个范围/查询如下:

查找区域(及其子区域)中的所有项目

祖先 gem 提供了一种将 Region 的后代类别作为数组检索的方法。在这种情况下,

ruby-1.9.2-p180 :167 > a = Region.find(4)
 => #<Region id: 4, name: "All", created_at: "2011-04-12 01:14:00", updated_at: "2011-04-12 01:14:00", ancestry: nil, cached_slug: "all"> 
ruby-1.9.2-p180 :168 > region_list = a.subtree_ids
 => [1, 2, 3, 4] 

如果数组中只有一个元素,则以下工作

items = Item.joins(:regions).where(["region_id =  ?", [1]])

生成的sql是

"SELECT `items`.* FROM `items` INNER JOIN `items_regions` ON `items_regions`.`item_id` = `items`.`id` INNER JOIN `regions` ON `regions`.`id` = `items_regions`.`region_id` WHERE (region_id =  1)"

但是,如果数组中有多个项目并且我尝试使用 IN

Item.joins(:regions).where(["region_id IN  ?", [1,2,3,4]])
ActiveRecord::StatementInvalid: Mysql::Error: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '1,2,3,4)' at line 1: SELECT `items`.* FROM `items` INNER JOIN `items_regions` ON `items_regions`.`item_id` = `items`.`id` INNER JOIN `regions` ON `regions`.`id` = `items_regions`.`region_id` WHERE (region_id IN  1,2,3,4)

生成的sql最后有错误

"SELECT `items`.* FROM `items` INNER JOIN `items_regions` ON `items_regions`.`item_id` = `items`.`id` INNER JOIN `regions` ON `regions`.`id` = `items_regions`.`region_id` WHERE (region_id IN  1,2,3,4)"

生成代码的最后一部分应该是 (region_id IN ("1,2,3,4"))

如果我手动编辑 sql 并运行它,我会得到我所期望的。

所以,两个问题:

  1. 我对单值案例的方法是否正确?
  2. sql生成是错误还是我配置错误?

谢谢艾伦

4

4 回答 4

3
.where('regions.id' => array)

无论您是指定一个值还是多个值,都应该适用于所有情况。

您的原始查询不起作用的原因是您实际上需要指定有效的 SQL。所以或者你可以做

.where('region_id IN (?)', [1,2,3,4])
于 2011-04-12T21:55:15.083 回答
1

其他响应者关于条件哈希的使用是正确的,但之后您遇到的具体问题与字段特异性有关:Mysql::Error: Unknown column 'items.region_id' in 'where Clause'

您正在尝试根据“region_id”绘制条件,但由于您没有明确给出表格,因此默认情况下使用“items”。听起来您的专栏实际上在“item_regions”表上。尝试这个:

where("item_regions.region_id IN (?)", [1,2,3,4])

或者:

where(:item_regions => {:region_id => [1,2,3,4]})
于 2011-04-18T23:33:39.787 回答
0

我认为在 Arel 中最简洁和最惯用的方法是嵌套哈希语法,它避免了字符串文字(以及对 HABTM 连接表的任何直接引用):

Item.joins(:regions).where(regions: { id: [1,2,3,4] })
于 2014-06-29T21:10:16.083 回答
0

你试过了吗

.where('region_id IN (?)', [1,2,3,4])

形式?您需要 () 有效。

于 2011-04-18T23:27:10.480 回答