如果我创建一个Foo类,一些继承它的STI类(Foo1,Foo2等)然后添加不同的has_many :bars
,我能够得到我想要的行为。每个班级的联想。例如:
class Foo < ApplicationRecord
has_many :bars
end
class Foo1 < Foo
has_many :bars, -> { where(user_id: 1) }
end
我希望能够在一个对象上调用bars
,并根据对象的状态获得不同的关联行为。这有效,但有没有办法在不设置STI的情况下完成?
我尝试在 foo.rb 中做所有事情但是我似乎正在加载我的第一个has_many :bars
定义,即使我做了类似的事情:
has_many :bars ... if some_method_returning_boolean?
has_many :bars ... if some_other_method_returning_boolean?
即使这确实有效,但它似乎有点笨拙。
我也考虑了范围,但据我了解范围,我必须调用foo.bars.something
和foo.bars.something_else
而不是依赖于对象foo
的状态来以不同的方式给我foo.bars
。此外,看起来范围仅涵盖has_many
定义的一部分,但无法修改:source
,:foreign_key
等参数,但我可能错了。
还有其他办法吗?
答案 0 :(得分:1)
也许以这种方式覆盖您的DoFn
方法会让您满意吗?
此bars
只返回super
的常规结果。
something_foo.bars
答案 1 :(得分:1)
STI是这样做的正确方法。通常可以理解,任何特定的模型类都应该与其他记录具有明确定义的一致的关系。
如果您的关系仅适用于某些类型的记录,而这些记录正是STI的用途:创建一个定义这些关系的子类。
你总是这么看。一个例子是“父”和“学生”都是基本类型“人”,但学生有belongs_to: parent
关联,父母有has_many: children
关系。
当然这假设父母不太可能成为学生,而学生父母,这个假设可能不正确。无论你做出什么样的假设,我都希望有一些认真思考这些限制是否相关或者过于偏执。
即使在技术上可以完成,在记录上切换类型通常也是不好的形式。如果您认为这是严格必要的,可以使用它来调整记录关系的定义方式。
一般来说,我建议你坚持一致的关系结构。那些不应与任何东西相关的记录不需要物理移除那些方法,它们可以在那里做而没有做任何有用的事情。无论如何,他们都是免费的。