14

私は小さなDataMapperのようなODMプロジェクトに取り組んでおり、ActiveModel::Validationsコンポーネントを利用しようとしています。ただし、テストの作成中に問題が発生しました。匿名クラスを使用してテストスキーマを構築していますが、バリデーターの実行に関しては、ActiveModel::Nameクラスがエラーをスローしています。 Class name cannot be blank. You need to supply a name argument when anonymous class given

再現する簡単なコード例を次に示します。

require 'active_model'

book_class = Class.new do
  include ActiveModel::Validations

  validates_presence_of :title

  def title; ""; end # This will fail validation
end

book_class.new.valid? # => throws error

例外は、失敗したバリデーターがある場合にのみ発生します-検証エラーメッセージを作成しようとしたときに問題が発生すると推測しています。だから私の質問は:

  • たくさん検索しましたが、似たようなことをしようとしている人は見つかりませんでした。これはActiveModelでは単純に不可能ですか、それとも私が知らない回避策がありますか?
4

2 に答える 2

21

ActiveModel は、エラー メッセージを設定するときにモデル名 (ここに表示されているように) を取得しようとします。これを回避する最も簡単な方法 (匿名クラスに名前を付ける以外) は、クラスmodel_nameに のインスタンスを返すクラス メソッドを与えることですActiveModel::Name

例えば

require 'active_model'

book_class = Class.new do
  include ActiveModel::Validations
  def self.model_name
    ActiveModel::Name.new(self, nil, "temp")
  end
  validates_presence_of :title

  def title; ""; end # This will fail validation
end

book_class.new.valid? # => no error
于 2013-01-21T02:57:38.873 に答える
10

ActiveModel::Name hereの初期化関数でエラーがスローされています。

module ActiveModel
  class Name
    def initialize(klass, namespace = nil, name = nil)
      @name = name || klass.name

      raise ArgumentError, "Class name cannot be blank. You need to supply a name argument when anonymous class given" if @name.blank?       
      # ...
    end
  end
end

model_nameしたがって、を返すクラス メソッドを定義するのではなく、を返すActiveModel::Nameクラス メソッドを定義できます。nameString

require 'active_model'

book_class = Class.new do
  include ActiveModel::Validations
  validates_presence_of :title

  def self.name
    "Book"
  end

  def title; ""; end # This will fail validation
end

book_class.new.valid? # => false
于 2014-10-02T19:39:13.550 に答える