Я реализовал свои первые отношения 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
Моя цель состоит в том, чтобы создать область / запрос следующим образом:
Найти все предметы в регионе (и его субрегионах)
Драгоценный камень предков предоставляет метод для извлечения категорий потомков для региона в виде массива. В этом случае
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 вручную и запускаю его, я получаю то, что ожидаю.
Итак, два вопроса:
- Верен ли мой подход к случаю с одним значением?
- Является ли создание sql ошибкой или я настроил неправильно?
Спасибо
Alan