简体   繁体   English

Rails 嵌套包含动态 class

[英]Rails nested includes with dynamic class

If I have a class A that has many B, but B is just the ID of a class, and can actually take the form of multiple different classes, can I eager load the associations of B dynamically based off what class it is?如果我有一个 class A,它有很多 B,但 B 只是一个 class 的 ID,并且实际上可以采用多个不同类的形式,我可以根据它是什么 class 动态加载 B 的关联吗?

For example, if B was the id of class Car, am I somehow able to eager load B.wheels.例如,如果 B 是 class Car 的 ID,我是否能够以某种方式急切加载 B.wheels。 But also if it's of type Dog, can I get B.Toys?但如果它是 Dog 类型,我可以获得 B.Toys 吗? This would all be through A, which of only one class type.这将全部通过 A,只有一个 class 类型。 I tried with syntax:我尝试使用语法:

 notifs = current_user.notifications.includes(target: [:wager_members, :disputes, :games])

Where notifications would be of class A, :target would be the dynamic class B, and:wager_members, :disputes, and:games would be the associations depending on what class B is.其中通知是 class A,:target 是动态的 class B,而:wager_members、:disputes 和:games 是关联,具体取决于 class B 是什么。

However, I get an error saying there is no class F for class B, which makes sense because class B dynamically changes.但是,我收到一条错误消息,指出 class B 没有 class F,这是有道理的,因为 class B 会动态变化。 Is there a way/syntax to load all nested associations in one fell swoop?有没有一种方法/语法可以一次性加载所有嵌套关联?

I'm wondering if I need to rethink model associations to make it feasible.我想知道是否需要重新考虑 model 关联以使其可行。

Polymorphic associations are key here: https://guides.rubyonrails.org/association_basics.html#polymorphic-associations多态关联是这里的关键: https://guides.rubyonrails.org/association_basics.html#polymorphic-associations

Here is roughly what your associations should look like at the class level以下是您的关联在 class 级别的大致情况

User
has_many :notifications

Notification
belongs_to :user
belongs_to :target

Target
belongs_to :notify, polymorphic: true # Can be any model

You should then be able to do something like this:然后你应该能够做这样的事情:

Notification.create(user: user, target: wager_member)
Notification.create(user: user, target: dispute)
Notification.create(user: user, target: game)

notifs = current_user.notifications.includes(target: [:wager_members, :disputes, :games])

notifs.first.target.notify.class.name # "WagerMember"

Really you can skip the target model and move the polymorphic association to the notification itself.实际上,您可以跳过目标 model 并将多态关联移动到通知本身。 Though may be useful if you need to add some custom logic.如果您需要添加一些自定义逻辑,虽然可能会有用。 This results in this:这导致:

Notification
belongs_to :user
belongs_to :target, polymorphic: true

notifs.first.target.class.name # "WagerMember"

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM