如何取消轨道中的多个模型?

时间:2017-10-27 09:44:20

标签: ruby-on-rails ruby activerecord acts-as-paranoid

我正在尝试取消下面的多个模型 具有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 

协会看起来像

2 个答案:

答案 0 :(得分:0)

我认为您可能采用的方法是手动取消操作,将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 

答案 1 :(得分: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.