Created
June 24, 2011 19:12
-
-
Save blt04/1045451 to your computer and use it in GitHub Desktop.
ActiveRecord self-referential many-to-many relationships with extra attributes
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class CreateExampleTables < ActiveRecord::Migration | |
def self.up | |
create_table :masters do |t| | |
t.string :fname | |
t.string :lname | |
t.timestamps | |
end | |
create_table :master_relations do |t| | |
t.integer :master_id, :null => false | |
t.integer :relation_id, :null => false | |
t.string :relation_type, :null => false | |
t.timestamps | |
end | |
end | |
def self.down | |
drop_table :masters | |
drop_table :master_relations | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# The relationship names could be improved, but this works | |
# Not sure if it is the most elegant way, but it should allow you to | |
# store and query relationship types | |
bt = Master.create(:fname => 'Brandon', :lname => 'Turner') | |
mt = Master.create(:fname => 'Marcia', :lname => 'Turner') | |
bt.master_relations.create(:relation => mt, :relation_type => 'Wife') | |
mt.master_relations.create(:relation => bt, :relation_type => 'Husband') | |
# All of Brandon's relations, regardless of type | |
bt.relations | |
=> [#<Master id: 2, fname: "Marcia", lname: "Turner"] | |
# Brandon's wives? | |
bt.relations_by('Wife') | |
=> [#<Master id: 2, fname: "Marcia", lname: "Turner"] | |
# Brandon's husbands? | |
bt.relations_by('Husband') | |
=> [] | |
# Who is Brandon a husband to? | |
bt.inverse_relations_by('Husband') | |
=> [#<Master id: 2, fname: "Marcia", lname: "Turner"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Master < ActiveRecord::Base | |
has_many :master_relations | |
has_many :inverse_master_relations, :class_name => 'MasterRelation', :foreign_key => :relation_id | |
has_many :relations, :through => :master_relations | |
has_many :inverse_relations, :through => :inverse_master_relations, :source => :master | |
def relations_by(relation_type) | |
relations.where(:master_relations => {:relation_type => relation_type}) | |
end | |
def inverse_relations_by(relation_type) | |
inverse_relations.where(:master_relations => {:relation_type => relation_type}) | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class MasterRelation < ActiveRecord::Base | |
belongs_to :master | |
belongs_to :relation, :class_name => 'Master' | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment