开发者

Validation in Rails without a model

开发者 https://www.devze.com 2023-01-13 03:49 出处:网络
I have a form that allows the user to send a message to an email, and I want to add validation to it. I do not have a model for this, only a controller. How should I do this in Rails?

I have a form that allows the user to send a message to an email, and I want to add validation to it. I do not have a model for this, only a controller. How should I do this in Rails?

I was considering doing the validation in the controller, and displaying the开发者_StackOverflow errors to the user using the flash object. Is there a better way of doing this?


The best approach would be to wrap up your pseudo-model in a class, and add the validations there. The Rails way states you shouldn't put model behavior on the controllers, the only validations there should be the ones that go with the request itself (authentication, authorization, etc.)

In Rails 2.3+, you can include ActiveRecord::Validations, with the little drawback that you have to define some methods the ActiveRecord layer expects. See this post for a deeper explanation. Code below adapted from that post:

require 'active_record/validations'

class Email

  attr_accessor :name, :email
  attr_accessor :errors

  def initialize(*args)
    # Create an Errors object, which is required by validations and to use some view methods.
    @errors = ActiveRecord::Errors.new(self)
  end

  # Required method stubs
  def save
  end

  def save!
  end

  def new_record?
    false
  end

  def update_attribute
  end

  # Mix in that validation goodness!
  include ActiveRecord::Validations

  # Validations! =)
  validates_presence_of :name
  validates_format_of :email, :with => SOME_EMAIL_REGEXP
end

In Rails3, you have those sexy validations at your disposal :)


For Rails 3+, you should use ActiveModel::Validations to add Rails-style validations to a regular Ruby object.

From the docs:

Active Model Validations

Provides a full validation framework to your objects.

A minimal implementation could be:

class Person
  include ActiveModel::Validations

  attr_accessor :first_name, :last_name

  validates_each :first_name, :last_name do |record, attr, value|
    record.errors.add attr, 'starts with z.' if value.to_s[0] == ?z
  end
end

Which provides you with the full standard validation stack that you know from Active Record:

person = Person.new
person.valid?                   # => true
person.invalid?                 # => false

person.first_name = 'zoolander'
person.valid?                   # => false
person.invalid?                 # => true
person.errors.messages          # => {first_name:["starts with z."]}

Note that ActiveModel::Validations automatically adds an errors method to your instances initialized with a new ActiveModel::Errors object, so there is no need for you to do this manually.

0

精彩评论

暂无评论...
验证码 换一张
取 消