Created
October 13, 2012 17:50
-
-
Save chrishunt/3885528 to your computer and use it in GitHub Desktop.
Relations in Ruby
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
require 'relations' | |
class Employee | |
extend Relations | |
belongs_to :manager | |
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
require 'manager' | |
require 'employee' | |
describe Employee do | |
let(:manager) { Manager.new } | |
it 'belongs to a manager' do | |
subject.manager.should be_nil | |
subject.manager = manager | |
subject.manager.should == manager | |
end | |
it "adds itself to the manager's list of employees" do | |
manager.employees.should be_empty | |
subject.manager = manager | |
manager.employees.should include subject | |
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
require 'relations' | |
class Manager | |
extend Relations | |
has_many :employees | |
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
require 'employee' | |
require 'manager' | |
describe Manager do | |
let(:employee) { Employee.new } | |
it 'has many employees' do | |
subject.employees.should be_empty | |
subject.employees << employee | |
subject.employees.size.should == 1 | |
subject.employees.should include employee | |
end | |
it "updates the employee's manager" do | |
employee.manager.should be_nil | |
subject.employees << employee | |
employee.manager.should == subject | |
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
module Relations | |
require 'active_support/inflector' | |
class RelationCollection < Array | |
def initialize(parent, parent_name, child_name) | |
@parent = parent | |
@parent_name = parent_name | |
@child_name = child_name | |
end | |
def <<(child) | |
unless child.send(@parent_name) == @parent | |
child.send "#{@parent_name}=", @parent | |
end | |
super unless include?(child) | |
end | |
end | |
def belongs_to(parent) | |
send(:attr_reader, parent) | |
define_method "#{parent}=" do |p| | |
instance_variable_set("@#{parent}", p) | |
p.send(self.class.name.underscore.pluralize) << self | |
end | |
end | |
def has_many(children) | |
define_method children do | |
collection = instance_variable_get "@#{children}" | |
unless collection | |
parent_name = self.class.name.underscore | |
collection = RelationCollection.new(self, parent_name, children) | |
instance_variable_set "@#{children}", collection | |
end | |
collection | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment