我有一个Order模型,它与VoyageLeg模型(后来属于一个端口)有两个关联,如下所示:
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
上的端口执行where子句,如下所示:
Order.joins(boarding_leg: :port).where(ports: {code: "AKL"}).count
但是如何在boarding_leg上为一个端口代码执行where子句,在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 :(得分: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