2011-04-12 1 views
0

첫 번째 HABTM 관계를 구현하면서 쿼리에 문제가 발생했습니다.Rails 3 HABTM 조건이 array 인 쿼리에 대한 올바른 형식

내 접근 방식을 검증하고 AREL (또는 레일스의 다른 부분) 코드에서 버그를 발견했는지 확인하고 싶습니다.

내가 가진 내가 items_regions 테이블에 연결 한

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 

다음 모델 :

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 

내 목표는 범위/쿼리입니다 만드는 것입니다은 다음과 같습니다

는 모든 항목 찾기 지역 (및 그 소구역)

ancestory gem은 ret Region의 자손 범주를 배열로 rieve합니다. 여러 항목이있을 경우이 경우,

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

인 배열을 사용하려고 시도합니다.

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 생성3210

는해야 말

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

생성 된 코드의 마지막 부분에서 오류가 (IN REGION_ID ("1,2,3,4"))

내가 편집하는 경우 SQL 수동으로 그것을 실행, 내가 기대하는 얻을.

그래서, 두 가지 질문 :

  1. 가 단일 값 케이스에 대한 나의 접근 방식이 맞습니까?
  2. SQL 생성이 버그가 있습니까? 또는 잘못 구성 되었습니까?

감사 앨런

답변

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

는 하나 개의 값 또는 여러을 지정 여부에 관계없이 모든 경우에 작동합니다.

원래 쿼리가 작동하지 않는 이유는 실제로 유효한 SQL을 지정해야한다는 것입니다. 그래서 대안으로 당신은 당신이

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

양식을 시도해 봤어

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

빠른 답변 감사드립니다. 나는 그것도 시도했다는 것을 언급하지 않았다 ... 'Item.joins (: regions) .where (: region_id => [1,2,3,4])'는 다음과 같은 오류를 준다 'ActiveRecord :: StatementInvalid : Mysql :: 오류 : 알 수없는 열 'items.region_id'에서 'where 절': SELECT'items'. * FROM'items' INNER JOIN'items_regions' ON'items_regions'.'item_id' ='items'.'id' INNER JOIN'지역'ON'지역'.'id' ='items_regions'.region_id' WHERE'items'.region_id'' (1, 2, 3, 4) '. WHERE 문이 items_regions가 아닌 items에 region_id를 연결하는 것처럼 보입니다. –

+0

여러 값이 아니라 하나의 값이 동일한 오류를 발생시킵니다. –

+0

IN (?) 위의 문제가 누락되었습니다. - 물음표 주변에 괄호가 있습니다. –

0

을 할 수 있습니까? 유효해야합니다().

+1

감사합니다. 너무 오랫동안 자신의 코드를 쳐다 보는 사람들만큼 눈이 멀지는 않습니다 :-) –

1

조건 해시 사용과 관련하여 다른 응답자가 올바르지 만 이후에 실행중인 특정 문제는 필드 특수성과 관련이 있습니다. Mysql :: Error : 알 수없는 열 'items.region_id'in ' clause '

"region_id"를 기반으로 조건을 그려야하지만 테이블을 명시 적으로 제공하지 않았기 때문에 기본적으로 "항목"이 사용됩니다. 귀하의 칼럼이 실제로 "item_regions"테이블에있는 것 같습니다. 이 시도 : 또는

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

또는를 :

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

내가 Arel에서이 작업을 수행 할 수있는 깨끗한 가장 관용적 인 방법은 문자열 리터럴을 방지 중첩 된 해시 구문 (과 HABTM에 대한 직접 참조 생각 테이블 조인) :

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