2017-02-07 23 views
2

у меня есть модель заказа, которая имеет две ассоциации с VoyageLeg Model (который затем принадлежит к порту), как показано ниже:Rails 4 вложенными, где положение на присоединяемой таблицы, которая имеет несколько ассоциаций

class Order < ActiveRecord::Base 
    belongs_to :boarding_leg, class_name: "VoyageLeg" 
    belongs_to :disembarking_leg, class_name: "VoyageLeg" 
end 

class VoyageLeg < ActiveRecord::Base 
    belongs_to :port 
    has_many :orders_boarding, class_name: "Order", inverse_of: :boarding_leg, :foreign_key => 'boarding_leg_id' 
    has_many :orders_disembarking, class_name: "Order", inverse_of: :disembarking_leg, :foreign_key => 'disembarking_leg_id' 
end 

я могу сделать где положение для порта на boarding_leg, как это:

Order.joins(boarding_leg: :port).where(ports: {code: "AKL"}).count 

Но как я могу сделать, где положение для одного порта кода на boarding_leg и другой код порта на disembarking_leg ??

когда я делаю это:

Order.joins(boarding_leg: :port).where(ports: {code: "ALK"}).joins(:disembarking_leg).where(ports: {code: "WLG"}).count 

в результате SQL является:

SELECT COUNT(*) FROM "orders" INNER JOIN "voyage_legs" ON "voyage_legs"."id" = "orders"."boarding_leg_id" AND "voyage_legs"."deleted_at" IS NULL INNER JOIN "ports" ON "ports"."id" = "voyage_legs"."port_id" AND "ports"."deleted_at" IS NULL INNER JOIN "voyage_legs" "disembarking_legs_orders" ON "disembarking_legs_orders"."id" = "orders"."disembarking_leg_id" AND "disembarking_legs_orders"."deleted_at" IS NULL WHERE "orders"."deleted_at" IS NULL AND "ports"."code" = 'ALK' AND "ports"."code" = 'WLG' 

Так что никогда не будет ничего возвращать, как код порта не может быть как WLG и AKL - Мне нужен способ имеют предложение where, специфичное для соединения.

+0

Хм, я не думаю, что есть простой способ сделайте это в ActiveRecord. В зависимости от того, какой БД вы используете, вам может потребоваться выполнить подзапрос или записать условия в предложение join. – max

+0

Я бы попробовал задать тот же вопрос, но поставил его как чистый SQL-запрос (а не рельсы) и добавил тег mysql или postgres, поскольку они, как правило, получают гораздо лучшие ответы. Просто создайте базовый план таблиц и каков желаемый результат. – max

+0

Спасибо, я сделаю некоторое исследование, чтобы узнать, могу ли я писать как SQL - его постгерскую базу данных, кстати, –

ответ

0

Лучшее, что я мог сделать (как предложил @max), было написать больше как SQL. Я создал псевдоним для соединения, а затем я могу сослаться на, специфическом присоединитесь к псевдониму портов присоединяется, а затем ссылаться на конкретный порт, как показано ниже:

Order.joins('INNER JOIN voyage_legs boarding_legs ON boarding_legs.id = orders.boarding_leg_id AND boarding_legs.deleted_at IS NULL INNER JOIN ports boarding_ports ON boarding_ports.id = boarding_legs.port_id AND boarding_ports.deleted_at IS NULL INNER JOIN voyage_legs disembarking_legs ON disembarking_legs.id = orders.disembarking_leg_id AND disembarking_legs.deleted_at IS NULL INNER JOIN ports disembarking_ports ON disembarking_ports.id = disembarking_legs.port_id AND disembarking_ports.deleted_at IS NULL').where('boarding_ports.code = :boarding_code AND disembarking_ports.code = :disembarking_code', boarding_code: "AKL", disembarking_code: "WLG").count