Skip to content

Commit

Permalink
Added code to support the :class_name attribute on object associations.
Browse files Browse the repository at this point in the history
class Comment < ActiveRecord::Base
  belongs_to :author, :class_name => "Person"
end

Previously, machinist would assume that the class name of :author is "Author".
So the blueprint had to explicitly make a "Person":

Comment.blueprint do
  author { Person.make }
end

This change looks at the associated object's class_name so that we can say:

Comment.blueprint do
  author
end
  • Loading branch information
tjsheehy committed Jan 10, 2009
1 parent 86fd205 commit 82e2b02
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 4 deletions.
3 changes: 2 additions & 1 deletion lib/machinist.rb
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,8 @@ def method_missing(symbol, *args, &block)
value = if block
block.call
elsif args.first.is_a?(Hash) || args.empty?
symbol.to_s.camelize.constantize.make(args.first || {})
klass = @object.class.reflect_on_association(symbol).class_name.constantize
klass.make(args.first || {})
else
args.first
end
Expand Down
33 changes: 30 additions & 3 deletions spec/machinist_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
# keep Machinist happy.
class InactiveRecord
include Machinist::ActiveRecordExtensions

def initialize(attributes = {})
self.protected_attributes ||= []
attributes = attributes.reject {|key, value| protected_attributes.include?(key) }
Expand All @@ -14,20 +14,40 @@ def initialize(attributes = {})
end
end

class_inheritable_accessor :associations
class_inheritable_accessor :protected_attributes

def self.attr_protected(attribute)
self.protected_attributes ||= []
self.protected_attributes << attribute
end

def self.belongs_to(association, options={})
attr_accessor association
self.associations ||= {}
class_name = (options[:class_name] || association).to_s.camelize
self.associations[association] = Association.new(class_name)
end

def self.reflect_on_association(association)
self.associations[association]
end

def save!; @saved = true; end
def reload; @reloaded = true; self; end

def saved?; @saved; end
def reloaded?; @reloaded; end
end

class Association
attr_accessor :class_name

def initialize(class_name)
@class_name = class_name
end
end

class Person < InactiveRecord
attr_accessor :id
attr_accessor :name
Expand All @@ -43,7 +63,8 @@ class Post < InactiveRecord
end

class Comment < InactiveRecord
attr_accessor :post
belongs_to :post
belongs_to :author, :class_name => "Person"
end

describe Machinist do
Expand Down Expand Up @@ -98,6 +119,12 @@ class Comment < InactiveRecord
Comment.make.post.class.should == Post
end

it "should create an associated object for an attribute with an association class name" do
Post.blueprint { }
Comment.blueprint { author }
Comment.make.author.class.should == Person
end

it "should call a passed-in block with the object being constructed" do
Person.blueprint { }
block_called = false
Expand Down

0 comments on commit 82e2b02

Please sign in to comment.