如何让模型验证与 Rails 中的视图层对话以提供简单的功能?
Posted
技术标签:
【中文标题】如何让模型验证与 Rails 中的视图层对话以提供简单的功能?【英文标题】:How to get model validations to talk with view layer in Rails to provide simple functionality? 【发布时间】:2012-06-23 22:09:37 【问题描述】:我有一个Room
模型,它验证了它的房间号是唯一的。但是,当用户创建一个新的 Room
实例时,如果他们尝试创建一个已经存在的房间,而不是显示标准的 这个房间已经存在 错误消息,我想提供一个链接到那个房间,以便他们可以编辑它。例如:我希望错误消息说:房间 x 已经存在。 单击此处编辑该房间。其中“单击此处”文本是指向该房间对象编辑路径的链接。
有没有办法在 Rails 中做到这一点或类似的东西?任何建议将不胜感激!
【问题讨论】:
在我的脑海中,如果验证失败,您可能会在验证中引发错误并在控制器中捕获该错误。如果控制器捕捉到它,您可以渲染一个包含编辑房间链接的特殊视图。 似乎可以使用 Ajax 或更简单地使用before_create
验证来返回“房间 #@room.number
已存在”并将用户重定向到该 Room
的更新页面(如果数字)不是唯一的。
【参考方案1】:
您可以使用 client_side_validations gem https://github.com/bcardarella/client_side_validations 在 javascript 中使用您的 ruby 验证(如果您使用的是 jquery),如 railscast #263 http://railscasts.com/episodes/263-client-side-validations 中所示。
您可以创建一个自定义验证器,它会找到现有的 room_id 并将指向它的链接传递给返回到您的视图的错误消息,例如:
# lib/room_existence_validator.rb
class RoomExistenceValidator < ActiveModel::EachValidator
def validate_each(object, attribute, value)
if existing_room = Room.find_by_id(value)
# unfortunately url_for helper is not defined here so it's hard-wired
room_link = "/rooms/#existing_room.id/edit"
object.errors[attribute] << "#link_to "Click here", room_link to edit that room"
end
end
end
您需要将 :validates => true 部分添加到您的 form_for 助手调用中。 现在它可以在没有 ajaxified 调用的情况下工作。
要使其与 ajax 一起使用,还有 2 件事要做:
a) 添加一个 rails.validations.custom.js 文件,看起来像这样:
# rails.validations.custom.js
# please beware the .remote in function-name
ClientSideValidations.validators.remote['existing_room'] = function(element, options)
if ($.ajax(
url: '/validators/existing_room',
data: id: element.val() ,
// async *must* be false
async: false
).status == 404) return options.message;
b) 路由您的验证请求,例如通过添加响应您的验证器路由的机架中间件,如 client_side_validations wiki https://github.com/bcardarella/client_side_validations/wiki/Custom-Validators 中所述
希望对你有所帮助:D
【讨论】:
以上是关于如何让模型验证与 Rails 中的视图层对话以提供简单的功能?的主要内容,如果未能解决你的问题,请参考以下文章