Ruby on Rails - 与需要连接的条件的has_many关系

时间:2015-03-19 15:20:13

标签: sql ruby-on-rails ruby-on-rails-3.2 associations

我在RoR 3..2.11工作。我有4个班:人,协议,关系和角色。我的情况如下:

这是人物:

has_many :relationships
has_many :agreements, {
  through: :relationships
}
has_many :current_agreements, {
  source: :agreements,
  through: :relationships,
  conditions: "agreements.start_date <= NOW() AND agreements.end_date >= NOW()"
}

这是关系:

belongs_to Role

新的角色已添加到数据库中(&#34;过去&#34;),以便可以将实时协议分配给其他人。协议上的前一个人仍然与协议有关系,但不应该在current_agreements下出现。所以我需要考虑relationships.role.name。像这样:

has_many :current_agreements, {
  source: :agreements,
  through: :relationships,
  conditions: "agreements.start_date <= NOW() AND agreements.end_date >= NOW() AND role.name != 'Past'"
}

这里的问题非常明确,角色不在查询中,因此role.name失败。有没有办法通过relationships.id为关联加入角色表?

我已经考虑过将current_agreements重新定义为一种方法,但是项目需要它在某些地方成为一个关联,所以我真的只是重新定义关联而不是重新分解整个事物。

2 个答案:

答案 0 :(得分:0)

我认为current_agreements 不应该成为关联。有没有说过

@person.current_agreements << @agreement

?如果是这样,这会设置开始日期和结束日期,以及相关的角色吗?

你说你不想重构它,但你可以花更多的时间试图通过将它作为一个关联来将方形钉钉入圆孔。

如协议的命名范围如何

#in Agreement
scope :current, includes(:role).where("agreements.start_date <= NOW() AND agreements.end_date >= NOW() AND role.name != 'Past'")

然后你可以说

@person.agreements.current

答案 1 :(得分:0)

我认为Max Williams是对的。这不应该是一种关系,我喜欢Max的方法。

但是听起来很复杂的事情,就是你不想重构。请记住,设计软件时,一件重要的事情就是为变化做好准备。如果很难重构,也许你应该看看你的测试,或者你的类的耦合方式。

看看Max的方法,它简单明了。使用Ruby / Rails(当然还有测试),重构可能很有趣,可以获得理想的行为。

我喜欢这个book。我之前的话可以解释得比我好。