5

如果这是一个非常常见和/或荒谬的问题,我们深表歉意;我发誓我已经多次阅读文档,所有内容似乎都如此专注于 ActiveRecord,以至于他们已经偏离了创建或编辑模型数据之外的表单路径。

以带有输入的表单为例,以控制某些统计数据的提取和显示。Rails 为我提供了什么来验证此表单的用户输入,它不会save在任何记录上调用?像:

  • :email必须是电子邮件地址
  • :num_products必须是正整数
  • :gender必须是“M”或“F”之一
  • :temperature必须在 -10 到 120 之间

等等(大多数网络框架中标准的那种东西)......

Rails 中有什么东西可以让我执行这个任意验证,还有一些视图助手来显示错误列表,还是所有东西都与 ActiveRecord 相结合?

如果我在文档中忽略了这一点,我深表歉意,但是并没有真正涵盖它,至少就 mt 疲倦的眼睛所能看出的而言。

抓头

感谢 Rob 的回答,这就是我想出的。我创建了一个实用程序类(恰当地命名为Validator),它只是嵌入到我的控制器中,用于任何需要它的东西。

module MyApp

    class Validator
        include ActiveModel::Validations
        include ActiveModel::Conversion
        extend  ActiveModel::Naming

        def initialize(attributes = {})
            super
            attributes.each { |n, v| send("#{n}=", v) if respond_to?("#{n}=") }
        end
    end

end

现在在控制器中,例如,只需定义一个小内联类:

class LoginController < ApplicationController
    class AuthenticationValidator < MyApp::Validator
        attr_accessor :email
        attr_accessor :password
        validates_presence_of :email, :message => "E-mail is a required field"
        validates_presence_of :password, :message => "Password cannot be blank"
    end

    def authenticate
        if request.post?
            @validator = AuthenticationValidator.new(params)
            if @validator.valid?
                # Do something meaningful
            end
        end
    end

.rb恕我直言,当逻辑更面向控制器时,将每一组验证规则都放在自己的位置上感觉有点不必要。可能有一种更简洁的方式来写这个,但我对 Ruby 和 Rails 还是很陌生。

4

2 回答 2

6

是的,它可以相当容易地完成。

您可以使用验证API。

例如,下面是一个联系我们模型,我将它用于不使用 ActiveRecord 的应用程序。

class ContactUs
  include ActiveModel::Validations
  include ActiveModel::Conversion
  extend ActiveModel::Naming

  attr_accessor :name, :email, :subject, :message
  validates_presence_of :name, :email, :message, :subject
  validates_format_of :email, :with => /\A[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4}\z/
  def initialize(attributes=nil)
    attributes.each do |name, value|
      send("#{name}=", value)
    end unless attributes.nil?
  end

  def persisted?
    false
  end
end
于 2011-05-02T14:14:59.047 回答
0

模型上有一个有效的方法,它会触发验证。

所以改为model.save,试试model.valid?

于 2011-05-02T14:14:15.317 回答