Validation in Rails without a model

匿名 (未验证) 提交于 2019-12-03 01:25:01

问题:

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 errors to the user using the flash object. Is there a better way of doing this?

回答1:

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 :)



回答2:

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.



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!