Rails 5如何在多个共享属性上的表之间形成关联

在Rails 5中,给定两个表之间的关系,涉及将它们连接到多个共享属性上,如何在与这些表对应的模型之间形成关联?

SQL:

SELECT * FROM trips JOIN stop_times ON trips.guid = stop_times.trip_guid AND trips.schedule_id = stop_times.schedule_id 

我尝试了以下配置,一般情况下…

 class Trip (trip){ where("stop_times.schedule_id = ?", trip.schedule_id) }, :inverse_of => :trip, :primary_key => :guid, :foreign_key => :trip_guid, :dependent => :destroy end class StopTime  :stop_times, :primary_key => :guid, :foreign_key => :trip_guid end Trip.first.stop_times.first #> StopTime object, as expected Trip.first.stop_times.first.trip #> Trip object, as expected 

…但是当我尝试在更高级的查询中使用它时,它会触发ArgumentError:关联范围’stop_times’是依赖于实例的(范围块接受参数)。 不支持预加载实例相关的作用域。

 Trip.joins(:stop_times).first #=> the unexpected ArgumentError StopTime.joins(:trip).first #> StopTime object, as expected 

我理解错误引用的内容,但我不确定如何解决它。

编辑:

我希望单个协会就足够了,但已经注意到两个不同的协会可以完成这项工作:

 class Trip (trip){ where("stop_times.schedule_id = ?", trip.schedule_id) }, :primary_key => :guid, :foreign_key => :trip_guid # use trip.stop_times instead of trip.joined_stop_times to avoid error about missing attribute due to missing join clause has_many :joined_stop_times, ->{ where("stop_times.schedule_id = trips.schedule_id") }, :class_name => "StopTime", :primary_key => :guid, :foreign_key => :trip_guid # use joins(:joined_stop_times) instead of joins(:stop_times) to avoid error about instance-specific association end Trip.first.stop_times Trip.eager_load(:joined_stop_times).to_a.first.joined_stop_times # executes a single query 

如果有人读这篇文章知道如何使用单一关联,请提及我。

我不认为这是正确的解决方案,但它可以提供帮助。 您可以添加另一个类似的实例独立关联,该关联仅用于预加载。 它将使用:joins:eager_load但不包括:includes

 class Trip < ApplicationRecord has_many :preloaded_stop_times, -> { where("stop_times.schedule_id = trips.schedule_id") }, class_name: "StopTime", primary_key: :guid, foreign_key: :trip_guid end # Usage trips = Trip.joins(:preloaded_stop_times).where(...) # ... # with :eager_load trips = Trip.eager_load(:preloaded_stop_times) trips.each do |trip| stop_times = trip.preloaded_stop_times # ... end