【问题标题】:Override ActiveRecord association condition覆盖 ActiveRecord 关联条件
【发布时间】:2013-12-18 13:57:06
【问题描述】:

我在 Rails 3.2 应用程序的 Project 模型中有这个关联:

has_many :pledges, conditions: { paid: true }

在一个地方,我需要所有未付的承诺。除了两个明显的解决方案(使用paid: false 条件定义另一个关联或使用Pledge.where... 查找承诺)之外,是否可以即时放弃条件?

类似于:

project.pledges.unscoped.where(paid: false)   # does not work since the link to project is also lost
project.pledges.where(paid: false)            # no good since it does "paid=t AND paid=f"

【问题讨论】:

    标签: ruby-on-rails activerecord ruby-on-rails-3.2


    【解决方案1】:

    为什么不向 Pledge 模型添加范围?

    class Pledge < ActiveRecord::Base
      scope :paid, -> {
        where(paid: true)
      }
      scope :unpaid, -> {
        where(paid: false)
      }
    end
    

    那么你可以这样做:

    project.pledges.paid
    project.pledges.unpaid
    

    您还需要从 Project 模型中的关联中删除条件。

    [编辑] 替代解决方案:

    在产品中为未付承诺添加第二个关联:

    class Product
      has_many :unpaid_pledges, class_name: Pledge, conditions: { paid: false }
    end
    

    那你就可以了

    project.pledges #these are all paid
    project.unpaid_pledges #all unpaid pledges belonging to product
    

    【讨论】:

    • 不是我想要的。模型中的条件是确保始终支付工作承诺。有点安全措施在那里强制执行。
    • 添加了一个替代方案,如果不求助于Pledge.where(...),不知道该怎么做。在 rails 中不可能在不删除关联本身的情况下删除关联范围
    • 糟糕,您在问题中提出了替代方案!无论如何,here's 一个类似的问题,还有另一种方式,Pledge.unscoped { product.pledges } 我认为是等价的
    • 不幸的是,上面的方法不起作用:Pledge.unscoped { project.pledges } 查询SELECT "pledges".* FROM "pledges" WHERE "pledges"."project_id" = 1652 AND "pledges"."paid" = 't' 所以条件仍然存在。但是,从链接的问题中,以下答案可以解决问题:Pledge.unscoped.where(project_id: project.id, paid: false)
    • 在这种情况下,您不需要 unscoped,除非 Pledge 模型具有默认范围。
    猜你喜欢
    • 2011-02-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-16
    • 1970-01-01
    • 2010-10-27
    相关资源
    最近更新 更多