2014-12-09 3 views
0

: through 및 : source 옵션을 통해 두 개의 유사한 다형성 연결을 사용하여 SQL 검색을 수행하려고합니다. 내가보고있는 것은 레일이 첫 번째 "has_many : reservation_trip_itinerary_entries ..."에 대한 테이블 이름 별칭을 남기고 있다는 것입니다.레일즈 : 조인에서 적절한 테이블 별명을 포함하지 않는 다형성 연관?

보너스 질문 : 연관성을 반환하지만 되돌릴 새로운 제휴 또는 별칭을 만들 수 있습니까? 백업 파일이 비어 있다면? 아마도 그것은 또 다른 질문의 가치가있을 것입니다.

class Reservation < ActiveRecord::Base 
    has_many :reservation_trips, :order => :departure_date, :dependent => :destroy 
    has_many :trip_types, :through => :reservation_trips # contact booking report                        
    has_many :reservation_trip_itinerary_entries, :through => :reservation_trips, :source => :itinerary_entries 
    has_many :trip_type_itinerary_entries, :through => :trip_types, :source => :itinerary_entries 

    # excluded irrelevant methods 

    def search 

     # many other search params excluded, all populating 'includes' and 
     # 'warez' in the same way 

     if params.key?(:itinerary_entry) and not params[:itinerary_entry].empty? 
      includes.push(:reservation_trip_itinerary_entries) 
      includes.push(:trip_type_itinerary_entries) 
      warez.push("(                                       
     (reservation_trip_itinerary_entries.action_type = '#{params[:itinerary_entry][:action_type]}' AND                 
     reservation_trip_itinerary_entries.action_id = #{params[:itinerary_entry][:action_id]})                   
     OR                                         
     (trip_type_itinerary_entries.action_type = '#{params[:itinerary_entry][:action_type]}' AND                   
     trip_type_itinerary_entries.action_id = #{params[:itinerary_entry][:action_id]})                     
)") 
     end 
     Reservation.includes(includes).where(warez.join(' AND ')).order('reservations.created_at DESC').limit(params[:limit]) 
    end 
: 여기
class ItineraryEntry < ActiveRecord::Base 

    default_scope order('position ASC') 

    attr_accessible :title, :code, :datetime, :position, :itinerary_type, :itinerary_id, :action_type, :action_id 
    belongs_to :itinerary, polymorphic: true 
    belongs_to :action, polymorphic: true 

가 (많은 ItineraryEntries에 상위) 예약이다 : 여기

는 (각각 별도의리스트를 포함 모두 TripType 지점 ReservationTrip 통해 예약에 자식)를 일정 항목이며

그리고 오류가 발생하는 SQL이 생성됩니다.

PG::Error: ERROR: missing FROM-clause entry for table "reservation_trip_itinerary_entries" 
LINE 2:   (reservation_trip_itinerary_entries.action_type = ... 
       ^

생각 :

여기
SELECT DISTINCT "reservations".id, 
       reservations.created_at AS alias_0 
FROM "reservations" 
LEFT OUTER JOIN "reservation_trips" ON "reservation_trips"."reservation_id" = "reservations"."id" 
LEFT OUTER JOIN "itinerary_entries" ON "itinerary_entries"."itinerary_id" = "reservation_trips"."id" 
AND "itinerary_entries"."itinerary_type" = 'ReservationTrip' 
LEFT OUTER JOIN "reservation_trips" "reservation_trips_reservations_join" ON "reservation_trips_reservations_join"."reservation_id" = "reservations"."id" 
LEFT OUTER JOIN "trip_types" ON "trip_types"."id" = "reservation_trips_reservations_join"."trip_type_id" 
LEFT OUTER JOIN "itinerary_entries" "trip_type_itinerary_entries_reservations" ON "trip_type_itinerary_entries_reservations"."itinerary_id" = "trip_types"."id" 
AND "trip_type_itinerary_entries_reservations"."itinerary_type" = 'TripType' 
WHERE (((reservation_trip_itinerary_entries.action_type = 'Activity' 
      AND reservation_trip_itinerary_entries.action_id = 3) 
     OR (trip_type_itinerary_entries.action_type = 'Activity' 
      AND trip_type_itinerary_entries.action_id = 3))) 
ORDER BY reservations.created_at DESC LIMIT 100 

는 SQL 오류입니다 : 두 번째 ("trip_type_itinerary_entries_reservations")을 수행하는 동안 "itinerary_entries"의 첫 번째 목록은 별칭이없는 방법에 주목? 감사!

답변

0

이걸 가지고 노는 후 ActiveRecord가 뉘앙스가 있다는 것을 발견했습니다. 첫 번째 연결 (원래 질문에서 "itinerary_entries"라는 이름의)에 별칭을 할당하지 않지만 모든 후속 연결에 별칭을 할당합니다.

그래서 나는 해킹의 일종으로 내 쿼리를 가지고 내 WHERE 절처럼 같은 :이 쿼리를 생산

if params.key?(:itinerary_entry) and not params[:itinerary_entry].empty? 
    includes.push(trip_types: [:itinerary_entries], reservation_trips: [:itinerary_entries]) 
    warez.push("                           
     (itinerary_entries.action_type = '#{params[:itinerary_entry][:action_type]}' AND         
     itinerary_entries.action_id = #{params[:itinerary_entry][:action_id]}) OR           
     (itinerary_entries_trip_types.action_type = '#{params[:itinerary_entry][:action_type]}' AND      
     itinerary_entries_trip_types.action_id = #{params[:itinerary_entry][:action_id]})         
    ") 
end 

SELECT DISTINCT "reservations".id, 
       reservations.created_at AS alias_0 
FROM "reservations" 
     LEFT OUTER JOIN "reservation_trips" 
        ON "reservation_trips"."reservation_id" = 
         "reservations"."id" 
     LEFT OUTER JOIN "itinerary_entries" 
        ON "itinerary_entries"."itinerary_id" = 
         "reservation_trips"."id" 
         AND "itinerary_entries"."itinerary_type" = 
          'ReservationTrip' 
     LEFT OUTER JOIN "reservation_trips" "reservation_trips_reservations_join" 
        ON "reservation_trips_reservations_join"."reservation_id" = 
         "reservations"."id" 
     LEFT OUTER JOIN "trip_types" 
        ON "trip_types"."id" = 
     "reservation_trips_reservations_join"."trip_type_id" 
     LEFT OUTER JOIN "itinerary_entries" "itinerary_entries_trip_types" 
        ON "itinerary_entries_trip_types"."itinerary_id" = 
         "trip_types"."id" 
         AND "itinerary_entries_trip_types"."itinerary_type" = 
          'TripType' 
WHERE ((itinerary_entries.action_type = 'Activity' 
      AND itinerary_entries.action_id = 3) 
      OR (itinerary_entries_trip_types.action_type = 'Activity' 
       AND itinerary_entries_trip_types.action_id = 3)) 
ORDER BY reservations.created_at DESC 
LIMIT 100