Simply Rich Association plugin

Plugin details

This plugin is based on Chad Fowler's Rails Recipe #18 : Self-referential Many-to-Many Relationships in Rails Recipe book. It manages the bidirectional link creation and deletion automatically.

Repositoryhttp://simply-rich-association.googlecode.com/svn/trunk/ Author Bala Paranj Tags association LicenseRuby's (MIT)

Documentation

Install the plugin:
ruby script/plugin install http://simply-rich-association.googlecode.com/svn/trunk/

== Usage

class Person < ActiveRecord::Base 
  has_and_belongs_to_many :friends, 
			:class_name => "Person", 
			:join_table => "friends_people", 
			:association_foreign_key => "friend_id", 
			:foreign_key => "person_id", 
			:after_add => :be_friendly_to_friend, 
			:after_remove => :no_more_mr_nice_guy 
	def be_friendly_to_friend(friend) 
	  friend.friends << self unless friend.friends.include?(self) 
	end 
	
	def no_more_mr_nice_guy(friend) 
	  friend.friends.delete(self) rescue nil 
	end 
end 


becomes:

class Person < ActiveRecord::Base 
  has_self_referential_many_to_many :friends
end


In the script/console you can see:

~/work/plugins/sra > script/console
Loading development environment.
>> p1 = Person.create :name => "Chad"
=> #, new_recordfalse, attributes{"name"=>"Chad", "id"=>48}, new_record_before_savetrue
>> p2 = Person.create :name => "Tintin"
=> #, new_recordfalse, attributes{"name"=>"Tintin", "id"=>49}, new_record_before_savetrue
>> p1.friends << p2
=> [#, new_recordfalse, friends[#, new_recordfalse, friends[....], attributes{"name"=>"Chad", "id"=>48}, new_record_before_savetrue], attributes{"name"=>"Tintin", "id"=>49}, new_record_before_savetrue]
>> p1.friends.size
=> 1
>> p2.friends.size
=> 1



It also provides syntactic sugar for ActiveRecord has_many :through macro:

For instance if you have a migration as:

class Subscription < ActiveRecord::Migration

  def self.up
    create_table :subscriptions do |t| 
      t.column :reader_id, :integer 
      t.column :magazine_id, :integer 
      t.column :last_renewal_on, :date 
      t.column :length_in_issues, :integer 
    end 

    create_table :magazines do |t| 
      t.column :title, :string 
    end 
    
    create_table :readers do |t| 
      t.column :name, :string 
    end 
  end

  def self.down
  end
end


and the models as:

class Subscription < ActiveRecord::Base 
belongs_to :reader 
belongs_to :magazine 
end 

class Reader < ActiveRecord::Base 
has_many :subscriptions 
has_many :magazines, :through => :subscriptions 
end

class Magazine < ActiveRecord::Base 
has_many :subscriptions 
has_many :readers, :through => :subscriptions 
end


using this plugin, your models become:

class Subscription < ActiveRecord::Base 
belongs_to :reader 
belongs_to :magazine 
end 

class Reader < ActiveRecord::Base 
has_many_through :magazines, :subscriptions
end

class Magazine < ActiveRecord::Base 
has_many_through :readers, :subscriptions
end


This example is based on Rails Recipe #22, Many-to-Many Relationships with
Extra Data of Chad Fowler's Rails Recipes book.

~/work/plugins/test/hmt > script/console
Loading development environment.
>> m = Magazine.create :title => "Ruby Illustrated"
=> #, new_recordfalse, attributes{"title"=>"Ruby Illustrated", "id"=>2}, new_record_before_savetrue
>> r = Reader.create :name => "TinTin"
=> #, new_recordfalse, attributes{"name"=>"TinTin", "id"=>2}, new_record_before_savetrue
>> s = Subscription.create(:last_renewal_on => Date.today, :length_in_issues => 6)
=> #>, @new_record=false, @attributes={"last_renewal_on"=>#, "id"=>2, "length_in_issues"=>6, "reader_id"=>nil, "magazine_id"=>nil}>
>> m.subscriptions << s
=> [#>, @new_record=false, @attributes={"last_renewal_on"=>#, "id"=>2, "length_in_issues"=>6, "reader_id"=>nil, "magazine_id"=>2}>]
>> r.subscriptions << s
=> [#>, @new_record=false, @attributes={"last_renewal_on"=>#, "id"=>2, "length_in_issues"=>6, "reader_id"=>2, "magazine_id"=>2}>]
>> s.save
=> true
>> m.readers
=> [#"TinTin", "id"=>"2"}]
>> r.magazines
=> [#"Ruby Illustrated", "id"=>"2"}]
>>

Further Documentation

There is currently no advanced documentation for this plugin.

New documentation

Edit plugin | Back in time (3 older versions) | Last edited by: hardway, 7 months ago