私は最初の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]
配列に要素が1つしかない場合、次のように機能します
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を手動で編集して実行すると、期待どおりの結果が得られます。
したがって、2つの質問:
- 単一値の場合の私のアプローチは正しいですか?
- SQL生成はバグですか、それとも正しく構成されていませんか?
ありがとうアラン