No commit activity in last 3 years
No release in over 3 years
Extend behavior of attributes of your active record models.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
 Dependencies

Runtime

~> 3.1.0
 Project Readme

Extended Attributes

Add custom behavior to your model attributes in ActiveRecord

How often do you have to have an instance method implemented in a model but only to work with just 1 attribute?

class User < ActiveRecord::Base

  def first_name
    name.split(' ').first
  end
  
  def about_in(format = :plain)
    case format
    when :plain; about
    when :html; RDiscount.new(about).to_html
    end
  end
  
end 

But attributes are also objects at the end of the day right? Should the first_name method belong to the attribute name? With this gem you can extend your attribute by mixing modules with them or having attribute specific methods defined on them. Just like our relationship objects.

In your Gemfile

gem 'extended_attributes'
$ bundle install

and now you can do:

class User < ActiveRecord::Base

  extend_attribute :name do
  
    def first
      split(' ').first
    end
  
    def last
      split(' ').last
    end
  
  end
  
end 

And you will be able to do:

user = User.find(:first) 
user.name # John Anderson 
user.name.first # John 
user.name.last # Anderson

Additionally, you can also have modules exteded on the attributes

module MarkdownMethods

  def to_html
    RDiscount.new(self).to_html # requies rdiscount gem
  end

end

class User < ActiveRecord::Base
  extend_attribute :about, :extend => MarkdownMethods
end

And...

@user.about # _This text should appear italic_
@user.about.to_html # <p><em>This text should appear italic</em></p>\n

Another example from examples folder

require 'net/http'
require 'uri'
require 'json'

module SocialProfiles
  
  def to_facebook
    "http://www.facebook.com/#{self}"
  end
  
  def to_twitter
    "http://www.twitter.com/#{self}"
  end
  
  def on_twitter?
    url = "http://api.twitter.com/1/users/show.json?screen_name=#{self}"
    json = Net::HTTP.get_response(URI.parse(url)).body
    JSON.parse(json)['error'].nil?
  end
  
end

class User < ActiveRecord::Base
  extend_attribute :username, :extend => SocialProfiles
end

And...

@user.username # chirantan
@user.username.to_twitter # http://www.twitter.com/chirantan
@user.username.on_twitter? # true
@user.username.to_facebook # http://www.facebook.com/chirantan

Why?

Extending attributes adds modularity to your design, better object orientation and makes interfaces clean.

Dealing with Fixnum

Fixnums cannot have singleton methods. Thus, if you try to extend an attribute that is a Fixnum, the whole behavior will be included on Fixnum class, which means that the same behavior will be available on all instances of Fixnum throughout your application. So be careful with them.

Note

This gem was developed because I liked it and it serves my purpose. Feel free to add to it. I’ll be happy to accept pull requests.