Using a class name:
aeroplane = create! Aeroplane,
:without => [:capacity, :safety_rating],
:merge => {:model_number => "567890"}
Using a symbol of the class name:
aeroplane = create! :aeroplane,
:without => [:capacity, :safety_rating],
:merge => {:model_number => "567890"}
Both of these versions will construct an Aeroplane object using the hash of parameters returned by the conventionally named method:
def aeroplane_standard_params
{
:model_number => "123456",
:name => "A630",
:manufacturer => "Airbus",
:safety_rating => "5",
:capacity => "200"
}
end
removing any attributes specified in the :without Array, and merging any attributes specified in the
:merge Hash.
We also added a :quantity attribute, which causes an Array of objects to be returned containing the number of objects specified. For example, :quantity => 2 would cause two Aeroplane objects to be returned:
plane1, plane2 = new :aeroplane, :quantity => 2
The "new" and "create!" methods look like this:
def new(klass, options={})
new_or_create(:new, klass, options)
end
def create!(sym, options={})
new_or_create(:create!, sym, options)
end
def new_or_create(operation, sym, options={})
raise ApplicationError.new("Option keys must be one of: [:without, :merge, :quantity]") /
unless options.without(:without, :merge, :quantity).empty?
klass, underscored = Class === sym ? [sym, sym.to_s.underscore] : [sym.to_s.camelize, sym]
src = <<-EOS
#{klass}.#{operation}(#{underscored}_standard_params.without(options[:without]).merge(options[:merge]||{}))
EOS
return eval(src) if options[:quantity].blank?
results = []
options[:quantity].times do
results << (eval src)
end
results
end
The notation also works well with nested objects. A pilot object can be merged in, using the pilot_standard_params for construction:
plane_with_pilot = new :aeroplane,
:merge => {
:model_number => "12345",
:pilot => new(:pilot)
}
One must be careful using Extract Method in tests. If you hide away important setup information or assertion code, then failing tests can sometimes be more difficult to fix. I make an exception in cases such as this, where unimportant information to the test is hidden away, thus making the important information more obvious to the reader.

0 comments:
Post a Comment