如何让模型验证与 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 中的视图层对话以提供简单的功能?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Rails 中验证日期?

Scaffold Rails 3 视图中的外键下拉列表

如何在没有模型的情况下验证 MVC3 中的强类型视图

Rails视图中的嵌套模型

Rails:在父模型的视图中创建一个 has_one 模型?

在哪里放置不是模型、视图、控制器或助手的 Rails 代码?