Ruby on rails 与可折叠模块作用域的模型关联

Ruby on rails 与可折叠模块作用域的模型关联,ruby-on-rails,Ruby On Rails,我有一个垃圾问题,允许用户丢弃(“删除”)某些东西 问题是,即使该项目可能被丢弃,但如果您查看的是较旧的项目,它仍然必须被引用。如果您现在这样做,它将找不到该对象,因为我已将默认\u范围更改为仅显示trashed为false的位置 这是我的垃圾模块: module Trashable extend ActiveSupport::Concern included do default_scope { where(trashed: false) } scope :tra

我有一个垃圾问题,允许用户丢弃(“删除”)某些东西

问题是,即使该项目可能被丢弃,但如果您查看的是较旧的项目,它仍然必须被引用。如果您现在这样做,它将找不到该对象,因为我已将
默认\u范围
更改为仅显示trashed为false的位置

这是我的垃圾模块:

module Trashable
  extend ActiveSupport::Concern

  included do
    default_scope   { where(trashed: false) }
    scope :trashed, -> { unscoped.where(trashed: true) }
    validates :trashed, inclusion: { in: [true, false] }
  end

  def trash
    update_attribute :trashed, true
  end
end
现在我有了一个
订单
模型,您可以在其中查看订单。例如,如果我们丢弃一个产品,我仍然希望用户能够查看他们的订单并看到该产品

现在,我无法使用模型关联访问它,例如:

有许多:产品
,并将其制作成既包括垃圾是假的,也包括垃圾是真的


有人知道如何做到这一点吗?

你可以做几件事:

  • 正如有人在评论中提到的,你应该使用Gem,这正是为了这个目的。使用该方法,您可以使用
    和_deleted
    only _deleted
    方法返回相关的已删除对象

  • 您不能像上面那样简单地使用
    unscoped
    。Unscoped将删除所有条件,而不仅仅是
    trashed:false
    。您还可以尝试创建另一个作用域,该作用域返回已删除的对象,并将在第二个作用域中找到的对象与第一个作用域合并

  • scope\u 1\u结果+scope\u 2\u结果


    如果您在Rails 5上,您还可以
    在Rails 4.x或更低版本中不可能实现的范围。

    您可以通过多种方式实现这一点,以下是我所知道的

    解决方案1使用以下内容定义

    module Trashable
      extend ActiveSupport::Concern
    
      included do
        default_scope   { where(trashed: false) }
        scope :trashed, -> { unscoped.where(trashed: true) }
    
        # Define a new scope here
        scope :with_trashed, -> { unscope(where: :trashed) }
        validates :trashed, inclusion: { in: [true, false] }
      end
    
      def trash
        update_attribute :trashed, true
      end
    end
    
    然后你可以像这样使用它:

    order.products.with_trashed
    
    order.unscope_products
    
    解决方案2定义非范围类

    class UnscopedProduct < Product
      self.default_scopes = []
      belongs_to :order
    end
    
    class Order < ActiveRecord::Base
      has_many :products
      has_many :unscoped_products, foreign_key: :order_id, class_name: "UnscopedProduct"
    end
    
    根据我的经验,我会使用解决方案1,但也有一些奇怪的情况,例如,在复杂查询中,这不再有效,所以请记住解决方案2,它将节省大量时间


    使用
    默认范围
    会给以后的复杂查询带来很多问题。那要看你了

    我认为您可以这样做,但您是否可以明确指定:
    有许多:产品,{unscope(:where)。where trashed:[true,false]}