activemodel 3.2.22.5 → 4.0.0.beta1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +85 -64
- data/MIT-LICENSE +1 -1
- data/README.rdoc +61 -24
- data/lib/active_model.rb +21 -11
- data/lib/active_model/attribute_methods.rb +150 -125
- data/lib/active_model/callbacks.rb +49 -34
- data/lib/active_model/conversion.rb +39 -19
- data/lib/active_model/deprecated_mass_assignment_security.rb +21 -0
- data/lib/active_model/dirty.rb +48 -32
- data/lib/active_model/errors.rb +176 -88
- data/lib/active_model/forbidden_attributes_protection.rb +27 -0
- data/lib/active_model/lint.rb +42 -55
- data/lib/active_model/locale/en.yml +3 -1
- data/lib/active_model/model.rb +97 -0
- data/lib/active_model/naming.rb +191 -51
- data/lib/active_model/railtie.rb +11 -1
- data/lib/active_model/secure_password.rb +55 -25
- data/lib/active_model/serialization.rb +51 -27
- data/lib/active_model/serializers/json.rb +83 -46
- data/lib/active_model/serializers/xml.rb +46 -12
- data/lib/active_model/test_case.rb +0 -12
- data/lib/active_model/translation.rb +9 -10
- data/lib/active_model/validations.rb +154 -52
- data/lib/active_model/validations/absence.rb +31 -0
- data/lib/active_model/validations/acceptance.rb +10 -22
- data/lib/active_model/validations/callbacks.rb +78 -25
- data/lib/active_model/validations/clusivity.rb +41 -0
- data/lib/active_model/validations/confirmation.rb +13 -23
- data/lib/active_model/validations/exclusion.rb +26 -55
- data/lib/active_model/validations/format.rb +44 -34
- data/lib/active_model/validations/inclusion.rb +22 -52
- data/lib/active_model/validations/length.rb +48 -49
- data/lib/active_model/validations/numericality.rb +30 -32
- data/lib/active_model/validations/presence.rb +12 -22
- data/lib/active_model/validations/validates.rb +68 -36
- data/lib/active_model/validations/with.rb +28 -23
- data/lib/active_model/validator.rb +22 -22
- data/lib/active_model/version.rb +4 -4
- metadata +23 -24
- data/lib/active_model/mass_assignment_security.rb +0 -237
- data/lib/active_model/mass_assignment_security/permission_set.rb +0 -40
- data/lib/active_model/mass_assignment_security/sanitizer.rb +0 -59
- data/lib/active_model/observer_array.rb +0 -147
- data/lib/active_model/observing.rb +0 -252
data/lib/active_model/railtie.rb
CHANGED
@@ -1,2 +1,12 @@
|
|
1
1
|
require "active_model"
|
2
|
-
require "rails"
|
2
|
+
require "rails"
|
3
|
+
|
4
|
+
module ActiveModel
|
5
|
+
class Railtie < Rails::Railtie # :nodoc:
|
6
|
+
config.eager_load_namespaces << ActiveModel
|
7
|
+
|
8
|
+
initializer "active_model.secure_password" do
|
9
|
+
ActiveModel::SecurePassword.min_cost = Rails.env.test?
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -2,15 +2,23 @@ module ActiveModel
|
|
2
2
|
module SecurePassword
|
3
3
|
extend ActiveSupport::Concern
|
4
4
|
|
5
|
+
class << self; attr_accessor :min_cost; end
|
6
|
+
self.min_cost = false
|
7
|
+
|
5
8
|
module ClassMethods
|
6
9
|
# Adds methods to set and authenticate against a BCrypt password.
|
7
10
|
# This mechanism requires you to have a password_digest attribute.
|
8
11
|
#
|
9
|
-
# Validations for presence of password, confirmation of password
|
10
|
-
# a
|
11
|
-
#
|
12
|
+
# Validations for presence of password on create, confirmation of password
|
13
|
+
# (using a +password_confirmation+ attribute) are automatically added. If
|
14
|
+
# you wish to turn off validations, pass <tt>validations: false</tt> as an
|
15
|
+
# argument. You can add more validations by hand if need be.
|
16
|
+
#
|
17
|
+
# If you don't need the confirmation validation, just don't set any
|
18
|
+
# value to the password_confirmation attribute and the the validation
|
19
|
+
# will not be triggered.
|
12
20
|
#
|
13
|
-
# You need to add bcrypt-ruby (~> 3.0.0) to Gemfile to use has_secure_password:
|
21
|
+
# You need to add bcrypt-ruby (~> 3.0.0) to Gemfile to use #has_secure_password:
|
14
22
|
#
|
15
23
|
# gem 'bcrypt-ruby', '~> 3.0.0'
|
16
24
|
#
|
@@ -21,31 +29,36 @@ module ActiveModel
|
|
21
29
|
# has_secure_password
|
22
30
|
# end
|
23
31
|
#
|
24
|
-
# user = User.new(:
|
32
|
+
# user = User.new(name: 'david', password: '', password_confirmation: 'nomatch')
|
25
33
|
# user.save # => false, password required
|
26
|
-
# user.password =
|
34
|
+
# user.password = 'mUc3m00RsqyRe'
|
27
35
|
# user.save # => false, confirmation doesn't match
|
28
|
-
# user.password_confirmation =
|
36
|
+
# user.password_confirmation = 'mUc3m00RsqyRe'
|
29
37
|
# user.save # => true
|
30
|
-
# user.authenticate(
|
31
|
-
# user.authenticate(
|
32
|
-
# User.find_by_name(
|
33
|
-
# User.find_by_name(
|
34
|
-
def has_secure_password
|
38
|
+
# user.authenticate('notright') # => false
|
39
|
+
# user.authenticate('mUc3m00RsqyRe') # => user
|
40
|
+
# User.find_by_name('david').try(:authenticate, 'notright') # => false
|
41
|
+
# User.find_by_name('david').try(:authenticate, 'mUc3m00RsqyRe') # => user
|
42
|
+
def has_secure_password(options = {})
|
35
43
|
# Load bcrypt-ruby only when has_secure_password is used.
|
36
|
-
# This is to avoid ActiveModel (and by extension the entire framework)
|
44
|
+
# This is to avoid ActiveModel (and by extension the entire framework)
|
45
|
+
# being dependent on a binary library.
|
37
46
|
gem 'bcrypt-ruby', '~> 3.0.0'
|
38
47
|
require 'bcrypt'
|
39
48
|
|
40
49
|
attr_reader :password
|
41
50
|
|
42
|
-
|
43
|
-
|
51
|
+
if options.fetch(:validations, true)
|
52
|
+
validates_confirmation_of :password
|
53
|
+
validates_presence_of :password, :on => :create
|
54
|
+
|
55
|
+
before_create { raise "Password digest missing on new record" if password_digest.blank? }
|
56
|
+
end
|
44
57
|
|
45
58
|
include InstanceMethodsOnActivation
|
46
59
|
|
47
60
|
if respond_to?(:attributes_protected_by_default)
|
48
|
-
def self.attributes_protected_by_default
|
61
|
+
def self.attributes_protected_by_default #:nodoc:
|
49
62
|
super + ['password_digest']
|
50
63
|
end
|
51
64
|
end
|
@@ -53,20 +66,37 @@ module ActiveModel
|
|
53
66
|
end
|
54
67
|
|
55
68
|
module InstanceMethodsOnActivation
|
56
|
-
# Returns self if the password is correct, otherwise false
|
69
|
+
# Returns +self+ if the password is correct, otherwise +false+.
|
70
|
+
#
|
71
|
+
# class User < ActiveRecord::Base
|
72
|
+
# has_secure_password validations: false
|
73
|
+
# end
|
74
|
+
#
|
75
|
+
# user = User.new(name: 'david', password: 'mUc3m00RsqyRe')
|
76
|
+
# user.save
|
77
|
+
# user.authenticate('notright') # => false
|
78
|
+
# user.authenticate('mUc3m00RsqyRe') # => user
|
57
79
|
def authenticate(unencrypted_password)
|
58
|
-
|
59
|
-
self
|
60
|
-
else
|
61
|
-
false
|
62
|
-
end
|
80
|
+
BCrypt::Password.new(password_digest) == unencrypted_password && self
|
63
81
|
end
|
64
82
|
|
65
|
-
# Encrypts the password into the password_digest attribute
|
83
|
+
# Encrypts the password into the +password_digest+ attribute, only if the
|
84
|
+
# new password is not blank.
|
85
|
+
#
|
86
|
+
# class User < ActiveRecord::Base
|
87
|
+
# has_secure_password validations: false
|
88
|
+
# end
|
89
|
+
#
|
90
|
+
# user = User.new
|
91
|
+
# user.password = nil
|
92
|
+
# user.password_digest # => nil
|
93
|
+
# user.password = 'mUc3m00RsqyRe'
|
94
|
+
# user.password_digest # => "$2a$10$4LEA7r4YmNHtvlAvHhsYAeZmk/xeUVtMTYqwIvYY76EW5GUqDiP4."
|
66
95
|
def password=(unencrypted_password)
|
67
|
-
@password = unencrypted_password
|
68
96
|
unless unencrypted_password.blank?
|
69
|
-
|
97
|
+
@password = unencrypted_password
|
98
|
+
cost = ActiveModel::SecurePassword.min_cost ? BCrypt::Engine::MIN_COST : BCrypt::Engine::DEFAULT_COST
|
99
|
+
self.password_digest = BCrypt::Password.create(unencrypted_password, cost: cost)
|
70
100
|
end
|
71
101
|
end
|
72
102
|
end
|
@@ -1,25 +1,21 @@
|
|
1
1
|
require 'active_support/core_ext/hash/except'
|
2
2
|
require 'active_support/core_ext/hash/slice'
|
3
|
-
require 'active_support/core_ext/array/wrap'
|
4
|
-
|
5
3
|
|
6
4
|
module ActiveModel
|
7
|
-
# == Active Model Serialization
|
5
|
+
# == Active \Model \Serialization
|
8
6
|
#
|
9
7
|
# Provides a basic serialization to a serializable_hash for your object.
|
10
8
|
#
|
11
9
|
# A minimal implementation could be:
|
12
10
|
#
|
13
11
|
# class Person
|
14
|
-
#
|
15
12
|
# include ActiveModel::Serialization
|
16
13
|
#
|
17
14
|
# attr_accessor :name
|
18
15
|
#
|
19
16
|
# def attributes
|
20
|
-
# {'name' =>
|
17
|
+
# {'name' => nil}
|
21
18
|
# end
|
22
|
-
#
|
23
19
|
# end
|
24
20
|
#
|
25
21
|
# Which would provide you with:
|
@@ -29,27 +25,28 @@ module ActiveModel
|
|
29
25
|
# person.name = "Bob"
|
30
26
|
# person.serializable_hash # => {"name"=>"Bob"}
|
31
27
|
#
|
32
|
-
# You need to declare
|
33
|
-
#
|
28
|
+
# You need to declare an attributes hash which contains the attributes you
|
29
|
+
# want to serialize. Attributes must be strings, not symbols. When called,
|
30
|
+
# serializable hash will use instance methods that match the name of the
|
31
|
+
# attributes hash's keys. In order to override this behavior, take a look at
|
32
|
+
# the private method +read_attribute_for_serialization+.
|
34
33
|
#
|
35
34
|
# Most of the time though, you will want to include the JSON or XML
|
36
35
|
# serializations. Both of these modules automatically include the
|
37
|
-
# ActiveModel::Serialization module, so there is no need to
|
38
|
-
# include it.
|
36
|
+
# <tt>ActiveModel::Serialization</tt> module, so there is no need to
|
37
|
+
# explicitly include it.
|
39
38
|
#
|
40
|
-
#
|
39
|
+
# A minimal implementation including XML and JSON would be:
|
41
40
|
#
|
42
41
|
# class Person
|
43
|
-
#
|
44
42
|
# include ActiveModel::Serializers::JSON
|
45
43
|
# include ActiveModel::Serializers::Xml
|
46
44
|
#
|
47
45
|
# attr_accessor :name
|
48
46
|
#
|
49
47
|
# def attributes
|
50
|
-
# {'name' =>
|
48
|
+
# {'name' => nil}
|
51
49
|
# end
|
52
|
-
#
|
53
50
|
# end
|
54
51
|
#
|
55
52
|
# Which would provide you with:
|
@@ -66,27 +63,55 @@ module ActiveModel
|
|
66
63
|
# person.to_json # => "{\"name\":\"Bob\"}"
|
67
64
|
# person.to_xml # => "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<serial-person...
|
68
65
|
#
|
69
|
-
# Valid options are <tt>:only</tt>, <tt>:except</tt
|
66
|
+
# Valid options are <tt>:only</tt>, <tt>:except</tt>, <tt>:methods</tt> and
|
67
|
+
# <tt>:include</tt>. The following are all valid examples:
|
68
|
+
#
|
69
|
+
# person.serializable_hash(only: 'name')
|
70
|
+
# person.serializable_hash(include: :address)
|
71
|
+
# person.serializable_hash(include: { address: { only: 'city' }})
|
70
72
|
module Serialization
|
73
|
+
# Returns a serialized hash of your object.
|
74
|
+
#
|
75
|
+
# class Person
|
76
|
+
# include ActiveModel::Serialization
|
77
|
+
#
|
78
|
+
# attr_accessor :name, :age
|
79
|
+
#
|
80
|
+
# def attributes
|
81
|
+
# {'name' => nil, 'age' => nil}
|
82
|
+
# end
|
83
|
+
#
|
84
|
+
# def capitalized_name
|
85
|
+
# name.capitalize
|
86
|
+
# end
|
87
|
+
# end
|
88
|
+
#
|
89
|
+
# person = Person.new
|
90
|
+
# person.name = 'bob'
|
91
|
+
# person.age = 22
|
92
|
+
# person.serializable_hash # => {"name"=>"bob", "age"=>22}
|
93
|
+
# person.serializable_hash(only: :name) # => {"name"=>"bob"}
|
94
|
+
# person.serializable_hash(except: :name) # => {"age"=>22}
|
95
|
+
# person.serializable_hash(methods: :capitalized_name)
|
96
|
+
# # => {"name"=>"bob", "age"=>22, "capitalized_name"=>"Bob"}
|
71
97
|
def serializable_hash(options = nil)
|
72
98
|
options ||= {}
|
73
99
|
|
74
|
-
attribute_names = attributes.keys
|
100
|
+
attribute_names = attributes.keys
|
75
101
|
if only = options[:only]
|
76
|
-
attribute_names &= Array
|
102
|
+
attribute_names &= Array(only).map(&:to_s)
|
77
103
|
elsif except = options[:except]
|
78
|
-
attribute_names -= Array
|
104
|
+
attribute_names -= Array(except).map(&:to_s)
|
79
105
|
end
|
80
106
|
|
81
107
|
hash = {}
|
82
108
|
attribute_names.each { |n| hash[n] = read_attribute_for_serialization(n) }
|
83
109
|
|
84
|
-
|
85
|
-
method_names.each { |n| hash[n] = send(n) }
|
110
|
+
Array(options[:methods]).each { |m| hash[m.to_s] = send(m) if respond_to?(m) }
|
86
111
|
|
87
112
|
serializable_add_includes(options) do |association, records, opts|
|
88
|
-
hash[association] = if records.
|
89
|
-
records.map { |a| a.serializable_hash(opts) }
|
113
|
+
hash[association.to_s] = if records.respond_to?(:to_ary)
|
114
|
+
records.to_ary.map { |a| a.serializable_hash(opts) }
|
90
115
|
else
|
91
116
|
records.serializable_hash(opts)
|
92
117
|
end
|
@@ -113,7 +138,6 @@ module ActiveModel
|
|
113
138
|
# @data[key]
|
114
139
|
# end
|
115
140
|
# end
|
116
|
-
#
|
117
141
|
alias :read_attribute_for_serialization :send
|
118
142
|
|
119
143
|
# Add associations specified via the <tt>:include</tt> option.
|
@@ -123,13 +147,13 @@ module ActiveModel
|
|
123
147
|
# +records+ - the association record(s) to be serialized
|
124
148
|
# +opts+ - options for the association records
|
125
149
|
def serializable_add_includes(options = {}) #:nodoc:
|
126
|
-
return unless
|
150
|
+
return unless includes = options[:include]
|
127
151
|
|
128
|
-
unless
|
129
|
-
|
152
|
+
unless includes.is_a?(Hash)
|
153
|
+
includes = Hash[Array(includes).map { |n| n.is_a?(Hash) ? n.to_a.first : [n, {}] }]
|
130
154
|
end
|
131
155
|
|
132
|
-
|
156
|
+
includes.each do |association, opts|
|
133
157
|
if records = send(association)
|
134
158
|
yield association, records, opts
|
135
159
|
end
|
@@ -1,5 +1,4 @@
|
|
1
1
|
require 'active_support/json'
|
2
|
-
require 'active_support/core_ext/class/attribute'
|
3
2
|
|
4
3
|
module ActiveModel
|
5
4
|
module Serializers
|
@@ -12,83 +11,87 @@ module ActiveModel
|
|
12
11
|
extend ActiveModel::Naming
|
13
12
|
|
14
13
|
class_attribute :include_root_in_json
|
15
|
-
self.include_root_in_json =
|
14
|
+
self.include_root_in_json = false
|
16
15
|
end
|
17
16
|
|
18
17
|
# Returns a hash representing the model. Some configuration can be
|
19
18
|
# passed through +options+.
|
20
19
|
#
|
21
20
|
# The option <tt>include_root_in_json</tt> controls the top-level behavior
|
22
|
-
# of +as_json+. If true
|
23
|
-
#
|
21
|
+
# of +as_json+. If +true+, +as_json+ will emit a single root node named
|
22
|
+
# after the object's type. The default value for <tt>include_root_in_json</tt>
|
23
|
+
# option is +false+.
|
24
24
|
#
|
25
25
|
# user = User.find(1)
|
26
26
|
# user.as_json
|
27
|
-
# # => { "
|
28
|
-
#
|
27
|
+
# # => { "id" => 1, "name" => "Konata Izumi", "age" => 16,
|
28
|
+
# # "created_at" => "2006/08/01", "awesome" => true}
|
29
|
+
#
|
30
|
+
# ActiveRecord::Base.include_root_in_json = true
|
29
31
|
#
|
30
|
-
# ActiveRecord::Base.include_root_in_json = false
|
31
32
|
# user.as_json
|
32
|
-
# # => {"id"
|
33
|
-
#
|
33
|
+
# # => { "user" => { "id" => 1, "name" => "Konata Izumi", "age" => 16,
|
34
|
+
# # "created_at" => "2006/08/01", "awesome" => true } }
|
34
35
|
#
|
35
|
-
# This behavior can also be achieved by setting the <tt>:root</tt> option
|
36
|
+
# This behavior can also be achieved by setting the <tt>:root</tt> option
|
37
|
+
# to +true+ as in:
|
36
38
|
#
|
37
39
|
# user = User.find(1)
|
38
|
-
# user.as_json(root:
|
39
|
-
# # =>
|
40
|
-
#
|
41
|
-
#
|
42
|
-
# The remainder of the examples in this section assume include_root_in_json is set to
|
43
|
-
# <tt>false</tt>.
|
40
|
+
# user.as_json(root: true)
|
41
|
+
# # => { "user" => { "id" => 1, "name" => "Konata Izumi", "age" => 16,
|
42
|
+
# # "created_at" => "2006/08/01", "awesome" => true } }
|
44
43
|
#
|
45
44
|
# Without any +options+, the returned Hash will include all the model's
|
46
|
-
# attributes.
|
45
|
+
# attributes.
|
47
46
|
#
|
48
47
|
# user = User.find(1)
|
49
48
|
# user.as_json
|
50
|
-
# # => {"id"
|
51
|
-
#
|
49
|
+
# # => { "id" => 1, "name" => "Konata Izumi", "age" => 16,
|
50
|
+
# # "created_at" => "2006/08/01", "awesome" => true}
|
52
51
|
#
|
53
|
-
# The <tt>:only</tt> and <tt>:except</tt> options can be used to limit
|
54
|
-
# included, and work similar to the +attributes+ method.
|
52
|
+
# The <tt>:only</tt> and <tt>:except</tt> options can be used to limit
|
53
|
+
# the attributes included, and work similar to the +attributes+ method.
|
55
54
|
#
|
56
|
-
# user.as_json(:
|
57
|
-
# # => {"id"
|
55
|
+
# user.as_json(only: [:id, :name])
|
56
|
+
# # => { "id" => 1, "name" => "Konata Izumi" }
|
58
57
|
#
|
59
|
-
# user.as_json(:
|
60
|
-
# # => {"name"
|
58
|
+
# user.as_json(except: [:id, :created_at, :age])
|
59
|
+
# # => { "name" => "Konata Izumi", "awesome" => true }
|
61
60
|
#
|
62
61
|
# To include the result of some method calls on the model use <tt>:methods</tt>:
|
63
62
|
#
|
64
|
-
# user.as_json(:
|
65
|
-
# # => {"id"
|
66
|
-
#
|
67
|
-
#
|
63
|
+
# user.as_json(methods: :permalink)
|
64
|
+
# # => { "id" => 1, "name" => "Konata Izumi", "age" => 16,
|
65
|
+
# # "created_at" => "2006/08/01", "awesome" => true,
|
66
|
+
# # "permalink" => "1-konata-izumi" }
|
68
67
|
#
|
69
68
|
# To include associations use <tt>:include</tt>:
|
70
69
|
#
|
71
|
-
# user.as_json(:
|
72
|
-
# # => {"id"
|
73
|
-
#
|
74
|
-
#
|
75
|
-
# {"id"
|
70
|
+
# user.as_json(include: :posts)
|
71
|
+
# # => { "id" => 1, "name" => "Konata Izumi", "age" => 16,
|
72
|
+
# # "created_at" => "2006/08/01", "awesome" => true,
|
73
|
+
# # "posts" => [ { "id" => 1, "author_id" => 1, "title" => "Welcome to the weblog" },
|
74
|
+
# # { "id" => 2, "author_id" => 1, "title" => "So I was thinking" } ] }
|
76
75
|
#
|
77
76
|
# Second level and higher order associations work as well:
|
78
77
|
#
|
79
|
-
# user.as_json(:
|
80
|
-
#
|
81
|
-
#
|
82
|
-
#
|
83
|
-
# # => {"id"
|
84
|
-
#
|
85
|
-
#
|
86
|
-
#
|
87
|
-
# {"comments"
|
88
|
-
#
|
78
|
+
# user.as_json(include: { posts: {
|
79
|
+
# include: { comments: {
|
80
|
+
# only: :body } },
|
81
|
+
# only: :title } })
|
82
|
+
# # => { "id" => 1, "name" => "Konata Izumi", "age" => 16,
|
83
|
+
# # "created_at" => "2006/08/01", "awesome" => true,
|
84
|
+
# # "posts" => [ { "comments" => [ { "body" => "1st post!" }, { "body" => "Second!" } ],
|
85
|
+
# # "title" => "Welcome to the weblog" },
|
86
|
+
# # { "comments" => [ { "body" => "Don't think too hard" } ],
|
87
|
+
# # "title" => "So I was thinking" } ] }
|
89
88
|
def as_json(options = nil)
|
90
|
-
root =
|
91
|
-
|
89
|
+
root = if options && options.key?(:root)
|
90
|
+
options[:root]
|
91
|
+
else
|
92
|
+
include_root_in_json
|
93
|
+
end
|
94
|
+
|
92
95
|
if root
|
93
96
|
root = self.class.model_name.element if root == true
|
94
97
|
{ root => serializable_hash(options) }
|
@@ -97,6 +100,40 @@ module ActiveModel
|
|
97
100
|
end
|
98
101
|
end
|
99
102
|
|
103
|
+
# Sets the model +attributes+ from a JSON string. Returns +self+.
|
104
|
+
#
|
105
|
+
# class Person
|
106
|
+
# include ActiveModel::Serializers::JSON
|
107
|
+
#
|
108
|
+
# attr_accessor :name, :age, :awesome
|
109
|
+
#
|
110
|
+
# def attributes=(hash)
|
111
|
+
# hash.each do |key, value|
|
112
|
+
# instance_variable_set("@#{key}", value)
|
113
|
+
# end
|
114
|
+
# end
|
115
|
+
#
|
116
|
+
# def attributes
|
117
|
+
# instance_values
|
118
|
+
# end
|
119
|
+
# end
|
120
|
+
#
|
121
|
+
# json = { name: 'bob', age: 22, awesome:true }.to_json
|
122
|
+
# person = Person.new
|
123
|
+
# person.from_json(json) # => #<Person:0x007fec5e7a0088 @age=22, @awesome=true, @name="bob">
|
124
|
+
# person.name # => "bob"
|
125
|
+
# person.age # => 22
|
126
|
+
# person.awesome # => true
|
127
|
+
#
|
128
|
+
# The default value for +include_root+ is +false+. You can change it to
|
129
|
+
# +true+ if the given JSON string includes a single root node.
|
130
|
+
#
|
131
|
+
# json = { person: { name: 'bob', age: 22, awesome:true } }.to_json
|
132
|
+
# person = Person.new
|
133
|
+
# person.from_json(json) # => #<Person:0x007fec5e7a0088 @age=22, @awesome=true, @name="bob">
|
134
|
+
# person.name # => "bob"
|
135
|
+
# person.age # => 22
|
136
|
+
# person.awesome # => true
|
100
137
|
def from_json(json, include_root=include_root_in_json)
|
101
138
|
hash = ActiveSupport::JSON.decode(json)
|
102
139
|
hash = hash.values.first if include_root
|