Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Creating Rails ActiveRecord model from params hash

Most Rails tutorials show how to populate a model class via the params hash like so:

class UsersController < ApplicationController   
    def create
        @user = User.create(params[:user])

        # more logic for saving user / redirecting / etc.     
    end  
end

This works great if all the attributes in your model are supposed to be strings. However, what happens if some of the attributes are supposed to be ints or dates or some other type?

For instance, let's say the User class looks like this

class User < ActiveRecord::Base
    attr_accessible :email, :employment_start_date, :gross_monthly_income
end

The :email attribute should be a string, the :employment_start_date attribute should be a date, and the :gross_monthly_income should be a decimal. In order for these attributes to be of the correct type, do I need to change my controller action to look something like this instead?

class UsersController < ApplicationController  
    def create
        @user = User.new
        @user.email = params[:user][:email]
        @user.employment_start_date = params[:user][:employment_start_date].convert_to_date
        @user.gross_monthly_income = params[:user][:gross_monthly_income].convert_to_decimal

        # more logic for saving user / redirecting / etc.
    end
end
like image 971
Kevin Pang Avatar asked Apr 14 '11 17:04

Kevin Pang


2 Answers

According to the ActiveRecord documentation, the attributes should automatically be typecasted based on the column types in the database.

like image 89
Kevin Pang Avatar answered Oct 21 '22 22:10

Kevin Pang


I would actually add a before_save callback in your users model to make sure that the values you want are in the correct format i.e.:

class User < ActiveRecord::Base
  before_save :convert_values

  #...

  def convert_values
    gross_monthly_income = convert_to_decimal(gross_monthly_income)
    #and more conversions
  end

end

So you can just call User.new(params[:user]) in your controller, which follows the motto "Keep your controllers skinny"

like image 44
Mike Lewis Avatar answered Oct 21 '22 23:10

Mike Lewis