验证消息帮助程序或检索验证错误

时间:2014-01-28 19:43:46

标签: ruby-on-rails ruby validation

P.S:我已经和Ruby一起工作了不到48小时,所以期待我愚蠢!

我已经在模型上设置了验证,一切正常。但是,我想修改由唯一性约束重新调整的消息。消息需要由执行一些额外处理的方法返回。

因此,例如,如果我尝试创建一个新的用户模型,其中“name”属性设置为“bob”,而bob命名帐户已经存在,我想显示一条消息,如“Bob is not available,click”这里查看当前鲍勃的帐户“。

因此,辅助方法将查找当前的bob帐户,获取本地化的字符串,并执行本地化字符串的常用字符串放置,将名称,链接到帐户以及我想要的任何其他信息放入消息中。

基本上我想要类似的东西:

validates_uniqueness_of :text, :message => self.uniquefound()

def uniquefound()
  return "some string i can make up myself with #{self.name}'s info in it"
end

毫无疑问,这是完全错误的......

如果这是不可能的,我发现我可以使用users.errors.added?来检测name属性是否添加了一个唯一的错误,从那里我可以做一些哈希操作来删除唯一错误,并且把它自己放在那里“after_validation”回调或控制器......还没有确切地知道如何做到这一点,但那是我的后备计划。

那么,有没有办法为消息提供类方法回调,并将当前模型传递给该方法(如果是静态方法)或调用它,以便在该方法中self为模型正在验证。

更新

在rails源代码中搜索,我发现在向错误类添加错误时调用此私有方法

private
    def normalize_message(attribute, message, options)
      case message
      when Symbol
        generate_message(attribute, message, options.except(*CALLBACKS_OPTIONS))
      when Proc
        message.call
      else
        message
      end
    end
  end

因此,如果我传递一个方法作为消息,我假设这个方法用于调用我的函数/方法并获取返回数据。但是它似乎没有在当前对象的范围内调用,也没有传递给错误所涉及的对象......

所以,如果我的挖掘是在正确的路径上,那么就不可能在当前对象上调用消息,或者调用传递对象的静态方法。

1 个答案:

答案 0 :(得分:3)

如果你真的需要这个功能,你可以这样做。

Class User < ActiveRecord::Base
   include Rails.application.routes.url_helpers
   ....
   validate :unique_name


   def unique_name
     original_user = User.where("LOWER(name) = ?", name.downcase)
     if original_user
       message = "#{name} is not available "
       message << ActionController::Base.helpers.link_to("Click Here",user_path(original_user))
       message << "to view the current #{name}'s account."
       errors.add(:name,message)
     end
  end
end

修改

使用Proc对象

Class User < ActiveRecord::Base
   include Rails.application.routes.url_helpers
   ....
   validates_uniqueness_of :name, message: Proc.new{|error,attributes| User.non_unique(attributes[:value]) }


   def self.non_unique(name)
     original_user = User.where("LOWER(name) = ? ", name.downcase)
     message = "#{name} is not available "
     message << ActionController::Base.helpers.link_to("Click Here",Rails.application.routes.url_helpers.user_path(original_user))
     message << "to view the current #{name}'s account."
   end
end

这些都会将以下错误消息添加到:name

"Name Bob is not available <a href=\"/users/10\">Click Here</a>to view the current Bob's account."