【问题标题】:Ruby on Rails - has_many relationship with condition that needs a joinRuby on Rails - has_many 与需要连接的条件的关系
【发布时间】:2015-03-19 15:20:12
【问题描述】:

我正在使用 RoR 3..2.11。我有 4 个类:Person、Agreement、Relationship 和 Role。我的情况如下:

这是当面的:

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

数据库中添加了一个新角色(“过去”),因此可以将实时协议分配给另一个人。所以协议上的前一个人仍然与协议有关系,但不应再出现在 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 失败。有没有办法通过关联的关系.id 加入角色表?

我曾考虑将 current_agreements 重新定义为一种方法,但项目需要它在某些地方成为关联,所以我真的宁愿重新定义关联而不是重新考虑整个事情。

【问题讨论】:

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


    【解决方案1】:

    我认为 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
    

    【讨论】:

      【解决方案2】:

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

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

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-06-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-09-26
        • 2011-06-23
        • 1970-01-01
        相关资源
        最近更新 更多