Monday, October 25, 2010

Create new class in Rails3 with hash parameters

This guide is about how to create new class with hash parameters, without ActiveRecord. If you don't want to use database to define a new object, this guide is for you. First, we create a new contact.rb file in "app/models" directory


class Contact
 include ActiveModel::Serialization
 attr_accessor :name, :company_name, :email, :phone, :comment

 def initialize(attributes = {})
  @name=attributes[:name]
  @company_name=attributes[:company_name]
  @email=attributes[:email]
  @phone=attributes[:phone]
  @comment=attributes[:comment]
 end
 
# persisted is important not to get "undefined method `to_key' for" error
 def persisted?
  false
 end 
 
end

And then you can use this model to create a new form, like ActiveRecord in controllers:

@contact=Contact.new

or

@contact=Contact.new(params[:contact])

Now we can use this object to send email to sales or save it to another object's text column with json. For example if there is a json_contact text column in User active_record object, users.rb:


Class User < ActiveRecord::Base
before_save :before_save_function

def before_save_function
  unless self.json_contact.is_a?(String) then
    # we need this condition because if we updating, must know if it is a String (json modelled class) or a Contact model class
    self.json_contact=self.json_contact.to_json
  end
  true
 end

 def contact
  unless self.json_contact.nil? then
   contact_hash = ActiveSupport::JSON.decode(self.json_contact).symbolize_keys.clone
   return Contact.new(contact_hash)
  else
   return nil
  end
 end

end

Then you can give a Contact object to User.json_contact like:

@user=... # your turn (find, or create) @contact=Contact.new(params[:contact]) @user.json_contact=@contact @user.save

Don't forget to restart your application after modifying anything in your models. Now you can get original User.contact as an object, and you can use it like Contact model:

contact_name=@user.contact.name

That's all

1 comment:

  1. This comment has been removed by a blog administrator.

    ReplyDelete

Note: Only a member of this blog may post a comment.