0

我正在尝试取消多个模型的范围,如下所示具有acts_as_paranoid的用户模型

class User
  acts_as_paranoid
  has_one :category
  has_one :brand
  has_one :item         

  INDEXED_FIELDS = {
    only: [:name],
    include: {
      category: { only: [:name] },
      item: { only:[:name] },
      brand: { only: [:name]},
    }
  }

  def custom_json
    Category.unscoped do
      Item.unscoped do
        Brand.unscoped do
          self.as_json(INDEXED_FIELDS)
        end
      end
    end
  end
end

用户模型具有以下关联,该关联也具有acts_as_paranoid

示例类别模型、品牌和项目模型具有相同的代码

class Category
  acts_as_paranoid
  belongs_to :user
end

我可以使用“N”个模型动态地执行此操作吗,例如遍历数组,如下所示

def custom_json
  [Category, Item, Brand].each do 
    # do unscoping 
  end
end 

协会看起来像

4

2 回答 2

1

我认为您可能采用的方法是手动取消类的范围,将其设置default_scopes[],然后将其放回原处。

classes_to_unscope = [Category, Item, Brand]
# remove default_scopes, saving them in previous_scopes
previous_scopes = classes_to_unscope.map do |klazz| 
  scopes = klazz.default_scopes
  klazz.default_scopes = []
  scopes
end 
self.as_json(INDEXED_FIELDS)
# put default_scopes back
classes_to_unscope.each_with_index do |klazz, i|
  klazz.default_scopes = previous_scopes[i]
end 
于 2017-10-27T10:20:34.397 回答
0

作为额外的方法:

def unscope_all(*models, &block)
    # the order does not matter, but preserve it
    blocks = [block] + models.reverse.map do |model|
      proc do |inner_block|
        model.unscoped { inner_block.call }
      end
    end

    blocks.inject do |inner, outer|
      proc { outer.call(inner) }
    end.call
  end

然后你会使用它:

unscope_all(Category, Item, Brand) do 
    # do unscoping 
  end

无范围陷阱:离开块时,您会失去“不可范围性”,因此请确保您不返回关系(它不会是无范围的)。相反,您必须在块中解决它(例如,通过返回一个数组where(...).to_a.

于 2021-05-05T11:59:03.150 回答