Associations are not being created (Using Rails 3, RSpec 2, Machinist 1)

149 views
Skip to first unread message

Lukas Rieder

unread,
May 18, 2011, 10:20:35 AM5/18/11
to Machinist Users
Hy,

I'll try to describe my problem as precisely as I can.

# The outline:

When I run all my tests in one run, the fail in many places where an
association is required to be there.
I'm having the following blueprints:

Publisher.blueprint do
name { Faker::Company.name }
end

Document.blueprint do
publisher { Publisher.make }
end

# The problem:

In Tests I use Document.make but they fail:

ActiveRecord::RecordInvalid:
Publisher must be filled out.

Digging down I found out that Machinist::Lathe is responsible for
evaluating the blueprints.
There is a method_missing hook that is assigning values:

def method_missing(symbol, *args, &block)
if attribute_assigned?(symbol)
# If we've already assigned the attribute, return that.
@object.send(symbol)
elsif @adapter.has_association?(@object, symbol) && !
nil_or_empty?(@object.send(symbol))
# If the attribute is an association and is already assigned,
return that.
@object.send(symbol)
else
# Otherwise generate a value and assign it.
assign_attribute(symbol, generate_attribute_value(symbol,
*args, &block))
end
end

Looking at the second case "If the attribute is an association and is
already assigned, return that" I inspected the value of
@object.send(symbol) and nil_or_empty?(@object.send(symbol)).
Turns out, that when I run my test suite @object.send(symbol) returns
nil.
BUT strangely nil_or_empty?(@object.send(symbol)) returns false!

So in my case Lathe assumes that the association is already assigned.
Therefore leaving it blank on a Document.make and the Document fails
to create due to validations.

I hope you can still follow my thoughts and findings.
My quickfix for getting my specs running again was to patching the
method nil_or_empty? in Machinist::Lathe with the following piece of
code:

Machinist::Lathe.class_eval do
def nil_or_empty?(object)
object.respond_to?(:empty?) ? (object.nil? || object.empty?) :
object.nil?
# former implemenation returning empty? => false for nil Objects
# object.respond_to?(:empty?) ? object.empty? : object.nil?
end
end

But I find this thing very strange, and I'm looking for answers to
that problem.

Since when does nil respond to 'empty?' ?
Is there some problem with Active* enhancements in its version 3?
Do ActiveRecord belongs_to relations have changed in version 3 to
return some weird object that responds to 'empty?' ?
Does Machinist do some other Object level magic?

Where can I start looking for such issues, might this problem be
better elevated to elsewhere?

Help is appreciated,

Cheers Lukas
Reply all
Reply to author
Forward
0 new messages