Rails 关联 has_many 和 has_many 通过相同的 STI 模型

Rails association has_many and has_many through on same STI model

我有一个型号Note。 注释非常有用,在整个应用程序中有很多用途。

我们有另一个模型用户,这些是 STI 之间的拆分 用户1 和 User2s

我们有第三个模型 Thing,它是属于 Users 的东西......我暂时把它留在那里,因为它会变得更复杂,(还有其他模型有点像 Things 可以同样做笔记)。

Note.rb
belongs_to :user #This signifies that the user wrote the note
belongs_to :notable, polymorphic: :true #This is what the note is referring to

User.rb
has_many :user_notes, class_name: "Note", foreign_key: "user_id" 
#signifies the note was written by the User

User1.rb < User
has_many :notes, as: :notable 
#Signifies the note was about the User1
has_many :things

User2.rb < User
has_many :notes, as: :notable 
#Signifies the note was about the User2


Thing.rb
belongs_to :user1
has_many :notes, as: :notable 
#The note is about the thing

这些可以是,但通常不是,自我参照(我写了一篇关于我自己的笔记)。

通常 User1s 会写关于 User2s 或 User2s Things 的注释,以便 User2 可以看到它们。

我认为我在重命名 user_notes 时采取了正确的路线。

我正在为如何将所有可能与我相关的笔记收集在一起而苦恼。 即假设我是 user1。 我想看看我写的笔记,还有其他人写的关于我的笔记,还有关于我的东西的笔记。

有简单的方法吗? 我正在为两点而苦苦挣扎。

  1. 如何连接关于我的东西的笔记?

    has_many :thing_notes, 通过: :things, 来源: :notes

有效,但我想知道这是否是接近它的正确方法。

此外,我对相反的方向(这也很有用)很感兴趣,在这种情况下,忽略谁可能写了便条,return 相关的用户 1,如果有的话。但是...

delegate :user1, to: :notable

如果用户 1 已经是潜在客户,则没有意义 notable_type。

  1. 如何整理我的所有笔记(任何类型)并 return 它们?

@user1.notes 

将return只是关于我的笔记

@user1.user_notes 

将 return 我写的笔记

@user1.thing_notes 

会return记录我的东西

我可以将它们合并在一起,但我会冒着出现烦人的重复的风险,而且当它们都是一种类型时进行多次数据库调用并丢失数据库顺序似乎是一种耻辱...

有没有明显的方法来获取我的所有笔记...?

Note.where("(user_id = :user1_id) OR (notable_id = :user1_id AND notable_type = 'User') OR (notable_type = 'Thing' AND notable_id IN (:things))", user1_id: user1.id, things:user1.thing_ids)

有点丑,只会越来越丑...

希望这对喜欢解决此类难题的人有意义...

对于排序规则,如果您使用的是 Rails 5,您可以这样做来简化原始 SQL:

Note.where(user: user1).or(Note.where(notable: user1)).or(Note.where(notable: user1.things))

如果您不使用 Rails 5,您可以包含此 gem 以获得相同的功能:https://github.com/Eric-Guo/where-or