0

私の Rails 3.2.11 アプリケーションでは、論理的に削除されたレコードを無視するために、条件をサポートする一意性バリデーターが必要です。GitHub でそれを行うプル リクエストを見つけました (https://github.com/rails/rails/pull/5321) が、この機能は現在の Rails リリースの一部ではないようです。次に、次のような UniquenessValidator クラスのパッチを作成しました。

module UniquenessValidatorExtension
  def build_relation(klass, table, attribute, value)
    relation = super
    relation.merge!(options[:conditions]) if options[:conditions]
    relation
  end
end

ActiveRecord::Validations::UniquenessValidator.send :include, UniquenessValidatorExtension

これをロードするために、イニシャライザを作成しました。問題は、私のメソッドが呼び出されないことです。私は何を間違っていますか?

現在のUniquenessValidatorクラスへのリンクは次のとおりです。

4

3 に答える 3

1

それがどのように機能するかincludeです:

module M; end

class C
  include M
end

C.ancestors # => [C, M, Object, Kernel, BasicObject] 

あなたの場合build_relation、元のクラスのメソッドが呼び出されます。JFYI、prependRuby 2.0 のメソッド:

class C1
  prepend M
end

C1.ancestors # => [M, C1, Object, Kernel, BasicObject]

あなたの場合、メソッドbuild_relationはモジュールから呼び出されます。

さて、今すぐメソッドUniquenessValidator全体を再度開いてオーバーライドできますbuild_relation

于 2013-01-26T11:51:17.400 に答える
0

メソッドが呼び出されない場合は、ActiveRecord::Base が「必要」になった後にモジュールをインクルードしたことを意味します。前に含めるようにしてください:

config.before_initialize do
  ActiveRecord::Validations::UniquenessValidator.send :include, UniquenessValidatorExtension
end
于 2013-01-26T11:42:26.027 に答える
0

問題は @nash によって説明されましたが、Ruby 1.9.x を使用しているため、これは解決策ではありません。それを機能させるために、元のメソッドにエイリアスを付けてから置き換えました。これで、エイリアス化されたメソッドを上書きメソッドから呼び出すことができました。

class ActiveRecord::Validations::UniquenessValidator < ActiveModel::EachValidator
  alias_method :build_relation_orig, :build_relation
  def build_relation(klass, table, attribute, value)
    relation = self.build_relation_orig(klass, table, attribute, value)
    relation = relation.and(options[:conditions]) if options[:conditions]
    relation
  end
end
于 2013-01-26T18:58:45.437 に答える