我已经在模型上设置了验证,一切正常。但是,我想修改由唯一性约束重新调整的消息。消息需要由执行一些额外处理的方法返回。
因此,例如,如果我尝试创建一个新的用户模型,其中“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
因此,如果我传递一个方法作为消息,我假设这个方法用于调用我的函数/方法并获取返回数据。但是它似乎没有在当前对象的范围内调用,也没有传递给错误所涉及的对象......
所以,如果我的挖掘是在正确的路径上,那么就不可能在当前对象上调用消息,或者调用传递对象的静态方法。
答案 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."