如何在具有validates_length_of的模型中使用相同的标记生成器?

时间:2010-02-28 13:55:21

标签: ruby-on-rails dry

我在模型中进行了以下验证:

validates_length_of :description,
  :minimum => 2, :on => :save,
  :message => "must be at least 2 words",
  :tokenizer => lambda {|text| text.scan(/\w+/)}

这很好用。当我向模型添加第二个字段时需要通过单词数进行验证,我声明

tokenize_by_words = lambda {|text| text.scan(/\w+/)}

位于模型顶部,并使用

:tokenizer => tokenize_by_words

这也很好,并保持一切干燥。但是,当我需要在多个模型中使用相同的标记化器时,它们都会崩溃。如果我这样创建config / initializers / tokenizers.rb:

class ActiveRecord::Base
  tokenize_by_words = lambda {|text| text.scan(/\w+/)}
end

并删除模型中的定义,我得到/Library/Ruby/Gems/1.8/gems/activerecord-2.3.5/lib/active_record/base.rb:1959:in 'method_missing': undefined local variable or method 'tokenize_by_words' for #<Class:0x10357e988> (NameError)

使用实例变量或用方法替换整个事件也不起作用。

我确信有一些令人眼花缭乱的明显缺失,但我能找到的唯一文件:tokenizer并不真正考虑DRY-ness :(

2 个答案:

答案 0 :(得分:2)

您应该将tokenizer定义为方法,即

class ActiveRecord::Base
  def foo(text)
    text.scan(/\w+/)
  end
end

现在使用此方法符号作为:tokenizer属性的值。

validates_length_of :description,
  :minimum => 2, :on => :save,
  :message => "must be at least 2 words",
  :tokenizer => :foo

答案 1 :(得分:1)

您将能够使用:symbol for tokenizer 请继续关注;)

class Article
  include ActiveModel::Model

  validates_length_of :content,
    :minimum => 10,
    :message => "must be at least 10 words",
    :tokenizer => :tokenize_by_words

  def tokenize_by_words(text)
    text.scan(/\w+/)
  end
end

Allow symbol as values for tokenizer of LengthValidator by kakipo · Pull Request #16381 · rails/rails