Skip to content

Instantly share code, notes, and snippets.

@ches
Created December 9, 2011 23:01
Show Gist options
  • Save ches/1453719 to your computer and use it in GitHub Desktop.
Save ches/1453719 to your computer and use it in GitHub Desktop.
Rails #3847
class Company < ActiveRecord::Base
has_many :relationships
has_many :users, :through => :relationships, :uniq => true, :dependent => :destroy
with_options :through => :relationships, :source => :user, :dependent => :destroy,
:extend => Associations::RelationshipExtension do |co|
co.has_many :advisors, :conditions => ["relationships.role = ?", ROLES[:advisor]]
co.has_many :incubators, :conditions => ["relationships.role = ?", ROLES[:incubator]]
co.has_many :past_investors, :conditions => ["relationships.role = ?", ROLES[:past_investor]]
co.has_many :referrers, :conditions => ["relationships.role = ?", ROLES[:referrer]]
co.has_many :team_members, :conditions => ["relationships.role = ?", ROLES[:team_member]]
end
end
class Relationship < ActiveRecord::Base
belongs_to :user
belongs_to :company
end
module Associations
# Extension methods for Relationship association proxies, such as custom
# instance-scoped aggregation functions, automatic attribute manipulations
# when associations are made, etc.
module RelationshipExtension
# Add to an association collection, automatically setting role attribute on
# the join model based on the name of the association.
#
# @example Create Relationship with 'Investor' role.
# Company.first.investors << User.first
def <<(*args)
# only makes sense for Company currently
if [Company].include? proxy_association.owner.class
role = proxy_association.reflection.name.to_s.titleize.singularize
Relationship.send(:with_scope, create: { role: role }) { super }
else
super
end
end
alias push <<
alias concat <<
end
end
require 'spec_helper'
describe Associations::RelationshipExtension do
context '#<<' do
let(:company) { Company.make! }
it 'delegates if association base model is not a Company' do
company.stub(:class) { User }
expect do
company.past_investors << User.make
end.to raise_error(ActiveRecord::RecordInvalid, /Role can't be blank/)
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment