2011-04-12 44 views
0

我正在實現我的第一個HABTM關係,並且遇到了與我的查詢有關的問題。Rails 3 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 

我的目標是創建一個範圍/查詢如下:

查找所有項目一個區域(及其子區域)

祖先的寶石提供了一種方法來ret將區域的後裔分類爲數組。在這種情況下,

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代是一個錯誤還是我配置錯誤的東西?

感謝 艾倫

回答

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

應該在所有情況下,無論是否指定一個值或多個。

原始查詢不起作用的原因是您實際上需要指定有效的SQL。所以,或者你可以做

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

感謝您的快速回答。我沒有提到我也試過這個...'Item.joins(:regions).where(:region_id => [1,2,3,4])'給出了以下錯誤'ActiveRecord :: StatementInvalid :Mysql ::錯誤:'where子句'中的未知列'items.region_id':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' items'.'region_id' IN(1,2,3,4)'。它看起來像WHERE語句附加region_id項目而不是items_regions。 – 2011-04-12 23:22:24

+0

一個值而不是多個給出相同的錯誤。 – 2011-04-12 23:25:05

+0

我錯過了上面問題IN(?) - 問號周圍的問題。 – 2011-04-18 23:55:19

0

你嘗試

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

形式?你需要()是有效的。

+1

謝謝 - 沒有那些盯着他們的代碼太久的人:-) – 2011-04-18 23:54:54

1

其他響應者在條件散列的使用方面是正確的,但是之後遇到的具體問題與字段特異性有關: Mysql :: Error:未知列'items.region_id'in'where子句'

你試圖繪製一個基於「region_id」的條件,但由於你沒有明確地給出一個表,它默認使用「條目」。這聽起來像你的專欄實際上在「item_regions」表上。試試這個:

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

或者:

where(:item_regions => {:region_id => [1,2,3,4]}) 
0

我覺得阿雷爾做到這一點最清潔和最慣用的方式是嵌套哈希語法避免了字符串(及任何直接引用HABTM加入表格):

Item.joins(:regions).where(regions: { id: [1,2,3,4] })