如何有条件地包含关联定义?

时间:2016-09-22 21:36:40

标签: ruby-on-rails ruby ruby-on-rails-5

如果我创建一个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.somethingfoo.bars.something_else而不是依赖于对象foo的状态来以不同的方式给我foo.bars。此外,看起来范围仅涵盖has_many定义的一部分,但无法修改:source:foreign_key等参数,但我可能错了。

还有其他办法吗?

2 个答案:

答案 0 :(得分:1)

也许以这种方式覆盖您的DoFn方法会让您满意吗? 此bars只返回super的常规结果。

something_foo.bars

答案 1 :(得分:1)

STI是这样做的正确方法。通常可以理解,任何特定的模型类都应该与其他记录具有明确定义的一致的关系。

如果您的关系仅适用于某些类型的记录,而这些记录正是STI的用途:创建一个定义这些关系的子类。

你总是这么看。一个例子是“父”和“学生”都是基本类型“人”,但学生有belongs_to: parent关联,父母有has_many: children关系。

当然这假设父母不太可能成为学生,而学生父母,这个假设可能不正确。无论你做出什么样的假设,我都希望有一些认真思考这些限制是否相关或者过于偏执。

即使在技术上可以完成,在记录上切换类型通常也是不好的形式。如果您认为这是严格必要的,可以使用它来调整记录关系的定义方式。

一般来说,我建议你坚持一致的关系结构。那些不应与任何东西相关的记录不需要物理移除那些方法,它们可以在那里做而没有做任何有用的事情。无论如何,他们都是免费的。