0

我有一个 ActiveRecord mixin(我认为你可以这样称呼它?),它为这些模型添加了各种默认范围和回调,以便确定多租户查询的范围。

我还希望能够修改该模型上现有的唯一性验证以包含范围。我发现我可以使用 看到所有验证Model.validators,所以我很自然地尝试像这样修改范围选项:

Model.validators
  .select{|v| v.is_a?(ActiveRecord::Validations::UniquenessValidator)}
  .map{|v| v.options[:scope] = :client_id }

..但是这会导致错误RuntimeError: can't modify frozen Hash,对于options哈希。有人知道我该怎么做吗?我知道它可能会涉及一些非常 hacky 的代码。

如果无法编辑它,也许我可以覆盖它或捕捉它或其他什么?

编辑 - 我发现了这个,这几乎正是我想要做的,但它在 Rails 3.2 中不起作用,我认为他们已经完全改变了验证的存储方式?任何人都可以帮助我/给我有关如何在 Rails 3 中使用它的指示吗?

4

1 回答 1

0

终于破解了。关键是_validate_callbacks

def scope_validators(foreign_key)
  new_callback_chain = self._validate_callbacks.reject do |callback|
    callback.raw_filter.is_a?(ActiveRecord::Validations::UniquenessValidator)
  end
  deleted = self._validate_callbacks - new_callback_chain
  (self._validate_callbacks.clear << new_callback_chain).flatten!
  deleted.each do |c|
    v = c.raw_filter
    v.attributes.each do |a|
      validates_uniqueness_of *v.attributes, v.options.merge(scope: foreign_key)
    end
  end
end

就像混在模型中的款待一样。

于 2013-07-19T17:02:53.060 回答