首页 > 解决方案 > Rails 多个多态关联?

问题描述

在我的程序中,我有表格 Riders、Drivers 和 Preferences。

每个 Rider 和 Driver 都有自己的一组对其他模型的排名偏好。(例如,Rider1有偏好[Driver1, Driver2, Driver3]的偏好)

class Rider
has_many :preferences, as: :preferable -> { order(position: :asc) }

# has other stuff like a rider's current driver (if they have one), etc.

end

class Driver
has_many :preferences, as: :preferable -> { order(position: :asc) }

# other things like a driver's car (and current passengers)

end

class Preference
belongs_to :preferable, polymorphic: true

# tbd what to put here

end

因为 aPreference可以属于 a Driveror Rider,所以我认为多态关联是最好的。

Preferences 表计划为一个单一的表,将包含所有骑手和司机的所有偏好。

除了每个 Preference 需要指向一个特定person.

但我不知道如何最好地做到这一点。似乎person必须骑手或司机。所以它似乎是另一个多态关联。

除了,添加Preference喜欢的东西belongs_to :person, polymorphic: true让我想知道,我会放下什么样的各自Rider关系Driver?在我看来,has_onehas_many似乎不太有意义。

这是我要完成的功能:

  1. 所有骑手或司机都应该有偏好,每个偏好都应该指向特定的人(相反类型)。
  2. 偏好应该是双向的。如果骑手的状态发生变化,在每个驾驶员的偏好中,该骑手将及时了解这些变化
  3. 获取司机或乘客的偏好,并检查特定首选实体的当前属性。

我想象播种是这样的(轻微的伪代码):


max = Rider.create!( 
  name: "Max",
  address: "Pike Place Market"
)

jacob = Driver.create!(
  name: "Jacob",
  address: "Seattle",
  total_space: 3
)

leo = Driver.create!(
  name: "Leo",
  address: "New York",
  total_space: 1
)

# This would create preferences [Jacob, Leo] for Max 
# such that he'd prefer Jacob over Max.
Preference.create!(
  preferable: max,
  person: jacob
);

Preference.create!(
  preferable: max,
  person: leo
);

关于如何处理骑手/司机偏好的任何想法?它是另一个多态关联吗?如果是这样,那么我应该在其他模型中添加Preference什么?

也许我的结构也很糟糕,如果是这样的话,我绝对愿意听取不同的想法。

标签: ruby-on-railsrubyactiverecordrails-activerecordruby-on-rails-6

解决方案


好吧,事实证明多态关联确实奏效了!

每个Preference都有一个preferrerandpreferable两个属性可以是 aRiderDriver

class Preference < ApplicationRecord
  belongs_to :preferrer, polymorphic: true, required: true
  belongs_to :preferable, polymorphic: true, required: true
end

Preference为 a创建一个Rider将是这样的:


someRider = Rider.create!(...)
someDriver = Driver.create!(...)

Preference.create!(
  preferrer: someRider,
  preferable: someDriver
)

然后我选择按顺序排列每个人的偏好created_at(这只是一个小爱好项目)。


推荐阅读