Coder Social home page Coder Social logo

schuetzm / acts_as_relation Goto Github PK

View Code? Open in Web Editor NEW

This project forked from hzamani/acts_as_relation

3.0 3.0 1.0 596 KB

Multi table Inheritance for rails

Home Page: http://hzamani.github.com/acts_as_relation/

License: MIT License

Ruby 95.88% JavaScript 2.23% CSS 1.89%

acts_as_relation's Introduction

ActsAsRelation

This gem helps implement multiple-table-inheritance (MTI) methods to your ActiveRecord models. By default, ActiveRecord only supports single-table inheritance (STI). MTI gives you the benefits of STI but without having to place dozens of empty fields into a single table.

Take a traditional e-commerce application for example… A product has common attributes (name, price, image …), while each type of product has its own attributes… pen has color, book has author and publisher and so on.

Installation

For Rails 4 installation add the following line to your Gemfile

gem 'acts_as_relation', '~> 1.0'

and

$ bundle install

If you are using Rails 3 you must use ‘~> 0.1’ version specifier in Gemfile.

Usage

acts_as_relation uses a polymorphic has_one association to simulate multiple-table inheritance. For the e-commerce example you would declare the product as a supermodel and all types of it as acts_as :product (if you prefer you can use their aliases is_a and is_a_superclass)

class Product < ActiveRecord::Base
  acts_as_superclass
end

class Pen < ActiveRecord::Base
  acts_as :product
end

class Book < ActiveRecord::Base
  acts_as :product
end

To make this work, you need to declare both a foreign key column and a type column in the model that declares superclass. To do this you can set :as_relation_superclass option to true on products create_table (or pass it name of the association):

create_table :products, :as_relation_superclass => true do |t|
  # ...
end

Or declare them as you do on a polymorphic belongs_to association, it this case you must pass name to acts_as in :as option:

change_table :products do |t|
  t.integer :producible_id
  t.string  :producible_type
end

class Pen < ActiveRecord::Base
  acts_as :product, :as => :producible
end

Now Pen and Book act as Product. This means that they inherit Product attributes, associations, validations and methods.

To see its functionality lets add some stuff to product:

class Product
  validates_presence_of :name, :price

  def to_s
    "#{name} $#{price}"
  end
end

now we can to things like this:

Pen.create :name => "Nice Pen", :price => 1.3, :color => "Red"
Pen.where "name = ?", "Some Pen"
pen = Pen.new
pen.valid?      # => false
pen.errors.keys # => [:name, :price]
Pen.first.to_s  # => "Nice Pen $1.3"

When you declare an acts_as relation, the declaring class automatically gains parent methods (includeing accessors) so you can access them directly.

On the other hand you can always access a specific object from its parent by calling specific method on it:

Product.first.specific # will return a specific product, a pen for example

Options

The acts_as relation support these options:

  • :as

  • :auto_join

  • :class_name

  • :dependent

when :auto_join option set to true (which is by default), every query on child will automatically joins the parent table. For example:

Pen.where("name = ?", "somename")

will result in the following SQL:

SELECT "pens".* FROM "pens" INNER JOIN "products" ON "products"."as_product_id" = "pens"."id" AND "products"."as_product_type" = 'Pen' WHERE (name = 'somename')

All other options are same as has_one options.

Note that support for :conditions and :include has been removed. In their place, you can use +where()+ and +includes()+:

acts_as :product, -> { where(color: "yellow") }

acts_as_relation's People

Contributors

den-sheleh avatar dgalarza avatar hzamani avatar jfrux avatar schuetzm avatar wharle90 avatar

Stargazers

 avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

Forkers

activefx

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.