Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In Rails, is there a way to specify a TYPE you'd like an attr_accessor to be, and validate it using built-in Rails validation?

I've never been able to find a nice way to do this, so I thought I'd ask.

For example, in an ActiveRecord model, database backed attributes are automatically type-converted to the appropriate database-backed types. If I have a Category model, and it has a couple of attributes, say name and category_id, if I go like this:

Category.new(params[:category])

Rails knows that name is a String and category_id is an Integer.

Let's say I have several transient/synthetic attributes that I want to validate, and they have specific types. I want to submit them from a form, and I'd like them to be automatically converted to either a String or an Integer or a Date (for example) based on how they're defined.

If I was to declare something in a Rails model like:

attr_accessor :some_number_variable
attr_accessor :some_date

Is there a built-in way to tell Rails "I'd like you to cast the former to an Integer and the latter to a Date, when I go Category.new(params[:category])" so long as params[:category][:some_number_variable] and params[:category][:some_date] are part of the data submitted to the controller (I realize the Date example might be a bit trickier given the many date formats out there).

like image 622
humandoing Avatar asked Mar 28 '11 18:03

humandoing


People also ask

What is Rails validation?

Rails validation defines valid states for each of your Active Record model classes. They are used to ensure that only valid details are entered into your database. Rails make it easy to add validations to your model classes and allows you to create your own validation methods as well.

What does Attr_accessor do in Ruby?

In Ruby, object methods are public by default, while data is private. To access and modify data, we use the attr_reader and attr_writer . attr_accessor is a shortcut method when you need both attr_reader and attr_writer .


2 Answers

As of Rails 5, there is the Attribute API which you can use like this:

class SomeModel < ActiveRecord::Base
  attribute :a_checkbox_name, :boolean, default: false
end

You can set defaults, and define your own types, among other nice things. Then you can validate these attributes (virtual or not) like any other DB backed one.

like image 52
Mauricio Pasquier Juan Avatar answered Sep 28 '22 08:09

Mauricio Pasquier Juan


attr_accesor just creates reader/writer methods, and it comes from Ruby, not Rails. The Rails method that I believe often gets confused is attr_accessible which serves a different purpose. If you want to cast when the attribute is read, you can just override the reader.

attr_accessor :some_number_variable

def some_number_variable
  @some_number_variable.to_i
end

This will at least give you the writer for free. This is the best solution I know for what (I think) you are describing.

EDIT: As far as validation is concerned, I believe that if you are using Rails 3, it will be much easier for you to perform validation on these sort of attributes (I haven't done it so I can't say for sure). Now that validations aren't tied directly into ActiveRecord, I'd believe it possible.

like image 28
theIV Avatar answered Sep 28 '22 09:09

theIV