rubiety/has_meta_data

View on GitHub
README.rdoc

Summary

Maintainability
Test Coverage
{<img src="https://secure.travis-ci.org/rubiety/has_meta_data.png?branch=master" alt="Build Status" />}[http://travis-ci.org/rubiety/has_meta_data]
{<img src="https://gemnasium.com/rubiety/has_meta_data.png" alt="Dependency Status" />}[https://gemnasium.com/rubiety/has_meta_data]
{<img src="https://codeclimate.com/github/rubiety/has_meta_data.png" />}[https://codeclimate.com/github/rubiety/has_meta_data]

== Has Meta Data

This plugin allows you to extend one of your models with additional supplementary data stored in another table through a has_one relationship.  The benefit of this plugin over a simple has_one is that the meta model class is dynamically defined (though extendable via the has_meta_data declaration) and fields on the meta model are automatically delegated to from the main model, allowing you to work solely with your primary model and not worry about the storage of the data in a separate meta table.  This plugin also automatically handles creation of the meta model if you set a field on your model that exists in the meta model table.  

Common use cases for this are database efficiency if only a small number of your records have a certain set of data or in conjunction with STI to accomplish something akin to Class Table Inheritance (CTI).

In short, it's a transparent way of splitting up data into two tables while still treating them as one model.  

== Installation
  
This gem works with Rails 3 only.

In your Gemfile:
  
  gem "has_meta_data"
  
== Basic Example

  ## Database Schema
  create_table :articles, :force => true do |t|
    t.string :title
    t.text :body
  end
  
  create_table :article_meta, :force => true do |t|
    t.references :article
    t.string :reference_link
    t.text :reference_note
  end
  
  ## Model
  class Article < ActiveRecord::Base
    has_meta_data
  end
  
  ## Exposed Class Methods & Scopes:
  Article.meta_data_class
  => Article::Meta
  Article.with_meta_data.all
  => (Articles that have associated meta data)
  Article.without_meta_data.all
  => (Articles with no associated meta data)
  
  ## Usage Examples:
  
  article = Article.create(:title => 'Title', :body => 'Body')
  article.has_meta_data?  # => false
  
  article.reference_link = 'http://benhughes.name/'
  article.has_meta_data?  # => true
  article.meta
  # => #<Article::Meta reference_link: "http://benhughes.name/", reference_note: nil>
  
  article = Article.create(:title => 'Title', :body => 'Body', :reference_link => 'http://benhughes.name/')
  article.has_meta_data?  # => true
  article.reference_link  # => "http://benhughes.name/"

== Changing the Defaults

You can control the name of the meta class, foreign key, and table name not unlike ActiveRecord associations:

  class Article < ActiveRecord::Base
    has_meta_data :class_name => 'AdditionalData', 
                  :foreign_key => 'news_article_id',
                  :table_name => 'news_article_additional_data'
  end


== Extending the Meta Data Class

Because you don't directly define the meta data class, you can specify a block of code to be run in its
context by passing a block to has_draft:
  
  class Article < ActiveRecord::Base
    belongs_to :user
    
    has_meta_data do
      belongs_to :some_author
      
      def do_something
        # Something
      end
    end
    
  end

== Running Tests

This gem uses appraisal to test with different versions of the dependencies. See Appraisal first for which versions are tested.

  # Just the gems locked in Gemfile.lock
  $ bundle exec rake test

  # All of the Appraisals:
  $ bundle exec rake all