Skip to content

Commit

Permalink
Added ActiveAttr::BlockInitializations, closes #33
Browse files Browse the repository at this point in the history
  • Loading branch information
cgriego committed Nov 3, 2011
1 parent c0e76ea commit 5e04485
Show file tree
Hide file tree
Showing 4 changed files with 107 additions and 11 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# ActiveAttr 0.3.0 (unreleased) #

* Added BlockInitialization

# ActiveAttr 0.2.2 (November 2, 2011) #

* Fixed all instances of modules' #initialize not invoking its superclass
Expand Down
40 changes: 29 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,10 @@ the attributes of your model.
attribute :last_name
end

p = Person.new
p.first_name = "Chris"
p.last_name = "Griego"
p.attributes #=> {"first_name"=>"Chris", "last_name"=>"Griego"}
person = Person.new
person.first_name = "Chris"
person.last_name = "Griego"
person.attributes #=> {"first_name"=>"Chris", "last_name"=>"Griego"}

### BasicModel ###

Expand All @@ -39,9 +39,27 @@ required for your model to meet the ActiveModel API requirements.
end

Person.model_name.plural #=> "people"
p = Person.new
p.valid? #=> true
p.errors.full_messages #=> []
person = Person.new
person.valid? #=> true
person.errors.full_messages #=> []

### BlockInitialization ###

Including the BlockInitialization module into your class will yield the model
instance to a block passed to when creating a new instance.

class Person
include ActiveAttr::BlockInitialization
attr_accessor :first_name, :last_name
end

person = Person.new do |p|
p.first_name = "Chris"
p.last_name = "Griego"
end

person.first_name #=> "Chris"
person.last_name #=> "Griego"

### MassAssignment ###

Expand All @@ -56,10 +74,10 @@ attribute.
attr_accessor :first_name, :last_name
end

p = Person.new(:first_name => "Chris")
p.attributes = { :last_name => "Griego" }
p.first_name #=> "Chris"
p.last_name #=> "Griego"
person = Person.new(:first_name => "Chris")
person.attributes = { :last_name => "Griego" }
person.first_name #=> "Chris"
person.last_name #=> "Griego"

## RSpec Integration ##

Expand Down
37 changes: 37 additions & 0 deletions lib/active_attr/block_initialization.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
require "active_attr/chainable_initialization"
require "active_support/concern"

module ActiveAttr
# BlockInitialization allows you to build an instance in a block
#
# Including the BlockInitialization module into your class will yield the
# model instance to a block passed to when creating a new instance.
#
# @example Usage
# class Person
# include ActiveAttr::BlockInitialization
# end
#
# @since 0.3.0
module BlockInitialization
extend ActiveSupport::Concern
include ChainableInitialization

# Initialize a model and build via a block
#
# @example
# person = Person.new do |p|
# p.first_name = "Chris"
# p.last_name = "Griego"
# end
#
# person.first_name #=> "Chris"
# person.last_name #=> "Griego"
#
# @since 0.3.0
def initialize(*)
super
yield self if block_given?
end
end
end
39 changes: 39 additions & 0 deletions spec/unit/active_attr/block_initialization_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
require "spec_helper"
require "active_attr/block_initialization"

module ActiveAttr
describe BlockInitialization do
subject { model_class.new("arg") {} }

let :model_class do
Class.new do
include InitializationVerifier
include BlockInitialization

def initialize(arg)
super
end
end
end

describe "#initialize" do
it "invokes the superclass initializer" do
should be_initialized
end

it "doesn't raise when not passed a block" do
expect { model_class.new("arg") }.not_to raise_error
end

it "yields the new instance" do
yielded_instance = nil

returned_instance = model_class.new("arg") do |yielded|
yielded_instance = yielded
end

returned_instance.should equal yielded_instance
end
end
end
end

0 comments on commit 5e04485

Please sign in to comment.