Metafy is a Gem for Rails 3 that makes it possible to easily add dynamic attributes to any ActiveRecord model. These lightweight, meta attributes work just like normal database column attributes on your ActiveRecord model and are fully searchable (i.e. you can find records by values contained in these dynamic attributes).
To apply Metafy to any ActiveRecord model, follow these simple steps:
-
Install
-
Add to Gemfile: gem ‘metafy’
-
Install required gems: bundle install
-
-
Add the ‘mattrs’ table to your database
-
Create migration: rails g metafy
-
Migrate your database: rake db:migrate
-
-
Add metafied attributes to any of your ActiveRecord models using the metafy class method:
-
Add to app/models/model.rb: metafy :attribute_name
-
Say you had a table named “users”:
mysql> desc users; +----------------+--------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +----------------+--------------+------+-----+---------+----------------+ | id | int(11) | NO | PRI | NULL | auto_increment | | username | varchar(255) | YES | MUL | NULL | | | email | varchar(255) | YES | MUL | NULL | | | created_at | datetime | YES | | NULL | | | updated_at | datetime | YES | | NULL | | +----------------+--------------+------+-----+---------+----------------+
And you wanted some lightweight, dynamic fields associated with the User model but didn’t necessarily want them in the schema then you could add them as meta attributes using metafy like so:
# app/models/user.rb class User < ActiveRecord::Base metafy :first_name, :last_name,:gender, :country, :language end
Now you can do things like:
>> user = User.meta_where( :first_name => 'Bevis' ).first >> user.first_name = 'Larry' >> user.save >> user.first_name => 'Larry'
OR create a new record with meta attributes:
>> user = User.new :first_name => 'Jerry', :last_name => 'Johnson' >> user.save
OR select using the meta_where scope:
>> num_johnsons = User.meta_where( :last_name => 'Johnson' ).count
OR select & order using standard rails relations:
>> num_johnsons = User.where( :m_country => { :meta_value => 'Canada' } ).order( 'm_last_name.meta_value ASC' )
OR chain where with meta_where:
>> users = User.where( 'users.email LIKE "%@gmail.com"' ).meta_where( :language => "French" )
Well, there isn’t much difference functionally between a normal database column and a meta attribute. But there may be sometimes when you want to add a more dynamic, lightweight attribute that doesn’t clutter your schema. That’s when you’d use metafy.
-
Version 1.0.3
-
Refactored the code a bit
-
Bug report? Faulty/incomplete documentation? Feature request? Please post an issue on ‘github.com/Caseproof/metafy/issues’. If its urgent, please contact me from my website at ‘blairwilliams.com/contact’
Copyright © 2004-2011 Caseproof, LLC, released under the MIT license