Navigation Menu

Skip to content

Commit

Permalink
Fix errors for four of the code samples
Browse files Browse the repository at this point in the history
The four code samples that fail to run are:

- Add attribute magic to objects. Fixed by introducing a Person
  instance variable.

- Tracking value changes. Fixed by replacing `attr_accessor` with
  `define_attribute_methods`, providing getter and setter methods
  for `name` and providing the missing `Person#save` method. A
  call to `Person#save` has to precede the `person.name = 'robert'`
  assignment, if we want `previous_changes` to include 'bob'.

- Adding `errors` interface to objects. Fixed by introducing a
  Person instance variable, assigning `nil` to its name and calling
  `Person#validate!`.

- Custom validators. Fixed by defining `HasNameValidator` before
  it is used by `ValidatorPerson`.

All the code samples can now be run smoothly.

Call Dirty#changes_applied in Person#save, instead of modifying instance vars.
  • Loading branch information
Peter Markou committed Mar 8, 2014
1 parent 1fbb905 commit f6ab778
Showing 1 changed file with 49 additions and 30 deletions.
79 changes: 49 additions & 30 deletions activemodel/README.rdoc
Expand Up @@ -49,7 +49,8 @@ behavior out of the box:
send("#{attr}=", nil)
end
end


person = Person.new
person.clear_name
person.clear_age

Expand Down Expand Up @@ -78,7 +79,21 @@ behavior out of the box:
class Person
include ActiveModel::Dirty

attr_accessor :name
define_attribute_methods :name

def name
@name
end

def name=(val)
name_will_change! unless val == @name
@name = val
end

def save
# do persistence work
changes_applied
end
end

person = Person.new
Expand All @@ -88,6 +103,7 @@ behavior out of the box:
person.changed? # => true
person.changed # => ['name']
person.changes # => { 'name' => [nil, 'bob'] }
person.save
person.name = 'robert'
person.save
person.previous_changes # => {'name' => ['bob, 'robert']}
Expand Down Expand Up @@ -116,7 +132,10 @@ behavior out of the box:
"Name"
end
end


person = Person.new
person.name = nil
person.validate!
person.errors.full_messages
# => ["Name cannot be nil"]

Expand Down Expand Up @@ -180,41 +199,41 @@ behavior out of the box:

* Validation support

class Person
include ActiveModel::Validations
class Person
include ActiveModel::Validations

attr_accessor :first_name, :last_name
attr_accessor :first_name, :last_name

validates_each :first_name, :last_name do |record, attr, value|
record.errors.add attr, 'starts with z.' if value.to_s[0] == ?z
end
end
validates_each :first_name, :last_name do |record, attr, value|
record.errors.add attr, 'starts with z.' if value.to_s[0] == ?z
end
end

person = Person.new
person.first_name = 'zoolander'
person.valid? # => false
person = Person.new
person.first_name = 'zoolander'
person.valid? # => false

{Learn more}[link:classes/ActiveModel/Validations.html]

* Custom validators

class HasNameValidator < ActiveModel::Validator
def validate(record)
record.errors[:name] = "must exist" if record.name.blank?
end
end

class ValidatorPerson
include ActiveModel::Validations
validates_with HasNameValidator
attr_accessor :name
end

class ValidatorPerson
include ActiveModel::Validations
validates_with HasNameValidator
attr_accessor :name
end

class HasNameValidator < ActiveModel::Validator
def validate(record)
record.errors[:name] = "must exist" if record.name.blank?
end
end

p = ValidatorPerson.new
p.valid? # => false
p.errors.full_messages # => ["Name must exist"]
p.name = "Bob"
p.valid? # => true
p = ValidatorPerson.new
p.valid? # => false
p.errors.full_messages # => ["Name must exist"]
p.name = "Bob"
p.valid? # => true

{Learn more}[link:classes/ActiveModel/Validator.html]

Expand Down

0 comments on commit f6ab778

Please sign in to comment.