model_attribute 2.0.0 → 2.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +8 -8
- data/.travis.yml +5 -0
- data/CHANGELOG.md +13 -0
- data/Gemfile +0 -1
- data/Guardfile +1 -1
- data/README.md +27 -1
- data/Rakefile +8 -1
- data/lib/model_attribute.rb +18 -57
- data/lib/model_attribute/casts.rb +74 -0
- data/lib/model_attribute/version.rb +1 -1
- data/model_attribute.gemspec +4 -1
- data/spec/model_attributes_spec.rb +58 -21
- data/spec/spec_helper.rb +0 -1
- metadata +6 -18
- data/lib/model_attribute/json.rb +0 -27
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
ZjQzN2Q4YWFiMzRhYTA1NTI0Y2RkNDNjOGZlZjg4Zjk3ZTU1NzlkMQ==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
ZTc1NmViMDUxNDhiNmIzMGJiYmNiMzE5ZWM2ZDFjMGVmM2EwNjQxNg==
|
7
7
|
SHA512:
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
MzM1MDY3M2Q0ZDE4MWViNjcwNjY4ZjI5OTg1ZjJkYjY5N2JlNWM2MmQyMTUx
|
10
|
+
ODRjZWVmNDI2NzIxODk4MmY0YmQ0MTY3NGM0OTk5OGExMTFjY2UwM2Q0MzQ2
|
11
|
+
MzMyY2FlM2M3ZDk5Zjc3YjUzYTY5NmIwNjQ3NjU1NjYxYjMyMWM=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
MmE3NmY2MmMyYmU3MmRiNzY5ZGRhNjQ3MzYxMDhlMzdiZjhlZTFiMDVhOTY3
|
14
|
+
MDU0M2Q1OGJjZjRkZGM5YjA3ZGYyY2E0OTBkNDUwMDAxM2Y1NmQ2MTUzOWZi
|
15
|
+
N2VkMmM5MzViMGQ3OWYyODljNTg3Y2E4ZGExZTVhMmQzMzgzODc=
|
data/.travis.yml
ADDED
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,19 @@
|
|
2
2
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
4
4
|
|
5
|
+
## 2.1.0
|
6
|
+
|
7
|
+
- **New feature**: default values. Allows you to specify a default value like
|
8
|
+
so:
|
9
|
+
```
|
10
|
+
class User
|
11
|
+
attribute :name, :string, default: 'Michelle'
|
12
|
+
end
|
13
|
+
|
14
|
+
User.new.name
|
15
|
+
# => 'Michelle'
|
16
|
+
```
|
17
|
+
|
5
18
|
## 2.0.0
|
6
19
|
|
7
20
|
- **Breaking change**: Rename to `ModelAttribute` (no trailing 's') to avoid name
|
data/Gemfile
CHANGED
data/Guardfile
CHANGED
@@ -29,7 +29,7 @@ watch ("Guardfile") do
|
|
29
29
|
exit 0
|
30
30
|
end
|
31
31
|
|
32
|
-
guard :rspec, cmd: "bundle exec rspec --format=Nc --format=documentation" do
|
32
|
+
guard :rspec, cmd: "bundle exec rspec --format=Nc --format=documentation", all_on_start: true do
|
33
33
|
require "guard/rspec/dsl"
|
34
34
|
dsl = Guard::RSpec::Dsl.new(self)
|
35
35
|
|
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# ModelAttribute
|
1
|
+
# ModelAttribute [![Build Status](https://travis-ci.org/yammer/model_attribute.svg?branch=master)](https://travis-ci.org/yammer/model_attribute)
|
2
2
|
|
3
3
|
Simple attributes for a non-ActiveRecord model.
|
4
4
|
|
@@ -6,6 +6,7 @@ Simple attributes for a non-ActiveRecord model.
|
|
6
6
|
- Type casting and checking.
|
7
7
|
- Dirty tracking.
|
8
8
|
- List attribute names and values.
|
9
|
+
- Default values for attributes
|
9
10
|
- Handles integers, booleans, strings and times - a set of types that are very
|
10
11
|
easy to persist to and parse from JSON.
|
11
12
|
- Supports efficient serialization of attributes to JSON.
|
@@ -164,6 +165,31 @@ class User
|
|
164
165
|
events += new_event
|
165
166
|
end
|
166
167
|
end
|
168
|
+
|
169
|
+
# Supporting default attributes
|
170
|
+
|
171
|
+
class UserWithDefaults
|
172
|
+
extend ModelAttribute
|
173
|
+
|
174
|
+
attribute :name, :string, default: 'Charlie'
|
175
|
+
end
|
176
|
+
|
177
|
+
UserWithDefaults.attribute_defaults # => {:name=>"Charlie"}
|
178
|
+
|
179
|
+
user = UserWithDefaults.new
|
180
|
+
user.name # => "Charlie"
|
181
|
+
user.read_attribute(:name) # => "Charlie"
|
182
|
+
user.attributes # => {:name=>"Charlie"}
|
183
|
+
# attributes_for_json omits defaults to keep the JSON compact
|
184
|
+
user.attributes_for_json # => {}
|
185
|
+
# you can add them back in if you need them
|
186
|
+
user.attributes_for_json.merge(user.class.attribute_defaults) # => {:name=>"Charlie"}
|
187
|
+
# A default isn't a change
|
188
|
+
user.changes # => {}
|
189
|
+
user.changes_for_json # => {}
|
190
|
+
|
191
|
+
user.name = 'Bob'
|
192
|
+
user.attributes # => {:name=>"Bob"}
|
167
193
|
```
|
168
194
|
|
169
195
|
## Installation
|
data/Rakefile
CHANGED
data/lib/model_attribute.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
require "model_attribute/version"
|
2
|
-
require "model_attribute/
|
2
|
+
require "model_attribute/casts"
|
3
3
|
require "model_attribute/errors"
|
4
4
|
require "time"
|
5
5
|
|
@@ -8,17 +8,19 @@ module ModelAttribute
|
|
8
8
|
|
9
9
|
def self.extended(base)
|
10
10
|
base.send(:include, InstanceMethods)
|
11
|
-
base.instance_variable_set('@attribute_names',
|
12
|
-
base.instance_variable_set('@attribute_types',
|
11
|
+
base.instance_variable_set('@attribute_names', [])
|
12
|
+
base.instance_variable_set('@attribute_types', {})
|
13
|
+
base.instance_variable_set('@attribute_defaults', {})
|
13
14
|
end
|
14
15
|
|
15
|
-
def attribute(name, type)
|
16
|
+
def attribute(name, type, opts = {})
|
16
17
|
name = name.to_sym
|
17
18
|
type = type.to_sym
|
18
19
|
raise UnsupportedTypeError.new(type) unless SUPPORTED_TYPES.include?(type)
|
19
20
|
|
20
|
-
@attribute_names
|
21
|
-
@attribute_types[name]
|
21
|
+
@attribute_names << name
|
22
|
+
@attribute_types[name] = type
|
23
|
+
@attribute_defaults[name] = opts[:default] if opts.key?(:default)
|
22
24
|
|
23
25
|
self.class_eval(<<-CODE, __FILE__, __LINE__ + 1)
|
24
26
|
def #{name}=(value)
|
@@ -47,6 +49,10 @@ module ModelAttribute
|
|
47
49
|
@attribute_names
|
48
50
|
end
|
49
51
|
|
52
|
+
def attribute_defaults
|
53
|
+
@attribute_defaults
|
54
|
+
end
|
55
|
+
|
50
56
|
module InstanceMethods
|
51
57
|
def write_attribute(name, value, type = nil)
|
52
58
|
name = name.to_sym
|
@@ -56,7 +62,7 @@ module ModelAttribute
|
|
56
62
|
type ||= self.class.instance_variable_get('@attribute_types')[name]
|
57
63
|
raise InvalidAttributeNameError.new(name) unless type
|
58
64
|
|
59
|
-
value = cast(value, type)
|
65
|
+
value = Casts.cast(value, type)
|
60
66
|
return if value == read_attribute(name)
|
61
67
|
|
62
68
|
if changes.has_key? name
|
@@ -80,6 +86,8 @@ module ModelAttribute
|
|
80
86
|
instance_variable_get(ivar_name)
|
81
87
|
elsif !self.class.attributes.include?(name.to_sym)
|
82
88
|
raise InvalidAttributeNameError.new(name)
|
89
|
+
else
|
90
|
+
self.class.attribute_defaults[name.to_sym]
|
83
91
|
end
|
84
92
|
end
|
85
93
|
|
@@ -106,19 +114,19 @@ module ModelAttribute
|
|
106
114
|
alias_method :eql?, :==
|
107
115
|
|
108
116
|
def changes
|
109
|
-
@changes ||= {}
|
117
|
+
@changes ||= {}
|
110
118
|
end
|
111
119
|
|
112
120
|
# Attributes suitable for serializing to a JSON string.
|
113
121
|
#
|
114
122
|
# - Attribute keys are strings (for 'strict' JSON dumping).
|
115
|
-
# - Attributes with a nil value are omitted to speed serialization.
|
123
|
+
# - Attributes with a default or nil value are omitted to speed serialization.
|
116
124
|
# - :time attributes are serialized as an Integer giving the number of
|
117
125
|
# milliseconds since the epoch.
|
118
126
|
def attributes_for_json
|
119
127
|
self.class.attributes.each_with_object({}) do |name, attributes|
|
120
128
|
value = read_attribute(name)
|
121
|
-
|
129
|
+
if value != self.class.attribute_defaults[name.to_sym]
|
122
130
|
value = (value.to_f * 1000).to_i if value.is_a? Time
|
123
131
|
attributes[name.to_s] = value
|
124
132
|
end
|
@@ -151,52 +159,5 @@ module ModelAttribute
|
|
151
159
|
end.join(', ')
|
152
160
|
"#<#{self.class} #{attribute_string}>"
|
153
161
|
end
|
154
|
-
|
155
|
-
def cast(value, type)
|
156
|
-
return nil if value.nil?
|
157
|
-
|
158
|
-
case type
|
159
|
-
when :integer
|
160
|
-
int = Integer(value)
|
161
|
-
float = Float(value)
|
162
|
-
raise "Can't cast #{value.inspect} to an integer without loss of precision" unless int == float
|
163
|
-
int
|
164
|
-
when :boolean
|
165
|
-
if !!value == value
|
166
|
-
value
|
167
|
-
elsif value == 't'
|
168
|
-
true
|
169
|
-
elsif value == 'f'
|
170
|
-
false
|
171
|
-
else
|
172
|
-
raise "Can't cast #{value.inspect} to boolean"
|
173
|
-
end
|
174
|
-
when :time
|
175
|
-
case value
|
176
|
-
when Time
|
177
|
-
value
|
178
|
-
when Date, DateTime
|
179
|
-
value.to_time
|
180
|
-
when Integer
|
181
|
-
# Assume milliseconds since epoch.
|
182
|
-
Time.at(value / 1000.0)
|
183
|
-
when Numeric
|
184
|
-
# Numeric, but not an integer. Assume seconds since epoch.
|
185
|
-
Time.at(value)
|
186
|
-
else
|
187
|
-
Time.parse(value)
|
188
|
-
end
|
189
|
-
when :string
|
190
|
-
String(value)
|
191
|
-
when :json
|
192
|
-
if Json.valid?(value)
|
193
|
-
value
|
194
|
-
else
|
195
|
-
raise "JSON only supports nil, numeric, string, boolean and arrays and hashes of those."
|
196
|
-
end
|
197
|
-
else
|
198
|
-
raise UnsupportedTypeError.new(type)
|
199
|
-
end
|
200
|
-
end
|
201
162
|
end
|
202
163
|
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
module ModelAttribute
|
2
|
+
module Casts
|
3
|
+
class << self
|
4
|
+
def cast(value, type)
|
5
|
+
return nil if value.nil?
|
6
|
+
|
7
|
+
case type
|
8
|
+
when :integer
|
9
|
+
int = Integer(value)
|
10
|
+
float = Float(value)
|
11
|
+
raise "Can't cast #{value.inspect} to an integer without loss of precision" unless int == float
|
12
|
+
int
|
13
|
+
when :boolean
|
14
|
+
if !!value == value
|
15
|
+
value
|
16
|
+
elsif value == 't'
|
17
|
+
true
|
18
|
+
elsif value == 'f'
|
19
|
+
false
|
20
|
+
else
|
21
|
+
raise "Can't cast #{value.inspect} to boolean"
|
22
|
+
end
|
23
|
+
when :time
|
24
|
+
case value
|
25
|
+
when Time
|
26
|
+
value
|
27
|
+
when Date, DateTime
|
28
|
+
value.to_time
|
29
|
+
when Integer
|
30
|
+
# Assume milliseconds since epoch.
|
31
|
+
Time.at(value / 1000.0)
|
32
|
+
when Numeric
|
33
|
+
# Numeric, but not an integer. Assume seconds since epoch.
|
34
|
+
Time.at(value)
|
35
|
+
else
|
36
|
+
Time.parse(value)
|
37
|
+
end
|
38
|
+
when :string
|
39
|
+
String(value)
|
40
|
+
when :json
|
41
|
+
if valid_json?(value)
|
42
|
+
value
|
43
|
+
else
|
44
|
+
raise "JSON only supports nil, numeric, string, boolean and arrays and hashes of those."
|
45
|
+
end
|
46
|
+
else
|
47
|
+
raise UnsupportedTypeError.new(type)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
private
|
52
|
+
|
53
|
+
def valid_json?(value)
|
54
|
+
(value == nil ||
|
55
|
+
value == true ||
|
56
|
+
value == false ||
|
57
|
+
value.is_a?(Numeric) ||
|
58
|
+
value.is_a?(String) ||
|
59
|
+
(value.is_a?(Array) && valid_json_array?(value)) ||
|
60
|
+
(value.is_a?(Hash) && valid_json_hash?(value) ))
|
61
|
+
end
|
62
|
+
|
63
|
+
def valid_json_array?(array)
|
64
|
+
array.all? { |value| valid_json?(value) }
|
65
|
+
end
|
66
|
+
|
67
|
+
def valid_json_hash?(hash)
|
68
|
+
hash.all? do |key, value|
|
69
|
+
key.is_a?(String) && valid_json?(value)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
data/model_attribute.gemspec
CHANGED
@@ -9,6 +9,10 @@ Gem::Specification.new do |spec|
|
|
9
9
|
spec.authors = ["David Waller"]
|
10
10
|
spec.email = ["dwaller@yammer-inc.com"]
|
11
11
|
spec.summary = %q{Attributes for non-ActiveRecord models}
|
12
|
+
spec.description = <<-EOF
|
13
|
+
Attributes for non-ActiveRecord models.
|
14
|
+
Smaller and simpler than Virtus, and adds dirty tracking.
|
15
|
+
EOF
|
12
16
|
spec.homepage = ""
|
13
17
|
spec.license = "MIT"
|
14
18
|
|
@@ -23,5 +27,4 @@ Gem::Specification.new do |spec|
|
|
23
27
|
spec.add_development_dependency "rspec-nc", "~> 0.2"
|
24
28
|
spec.add_development_dependency "guard", "~> 2.8"
|
25
29
|
spec.add_development_dependency "guard-rspec", "~> 4.3"
|
26
|
-
spec.add_development_dependency "pry-debugger"
|
27
30
|
end
|
@@ -1,10 +1,11 @@
|
|
1
1
|
class User
|
2
2
|
extend ModelAttribute
|
3
|
-
attribute :id,
|
4
|
-
attribute :paid,
|
5
|
-
attribute :name,
|
6
|
-
attribute :created_at,
|
7
|
-
attribute :profile,
|
3
|
+
attribute :id, :integer
|
4
|
+
attribute :paid, :boolean
|
5
|
+
attribute :name, :string
|
6
|
+
attribute :created_at, :time
|
7
|
+
attribute :profile, :json
|
8
|
+
attribute :reward_points, :integer, default: 0
|
8
9
|
|
9
10
|
def initialize(attributes = {})
|
10
11
|
set_attributes(attributes)
|
@@ -23,19 +24,29 @@ class UserWithoutId
|
|
23
24
|
end
|
24
25
|
|
25
26
|
RSpec.describe "a class using ModelAttribute" do
|
26
|
-
describe "
|
27
|
-
|
28
|
-
|
27
|
+
describe "class methods" do
|
28
|
+
describe ".attribute" do
|
29
|
+
context "passed an unrecognised type" do
|
30
|
+
it "raises an error" do
|
31
|
+
expect do
|
32
|
+
User.attribute :address, :custom_type
|
33
|
+
end.to raise_error(ModelAttribute::UnsupportedTypeError,
|
34
|
+
"Unsupported type :custom_type. " +
|
35
|
+
"Must be one of :integer, :boolean, :string, :time, :json.")
|
36
|
+
end
|
37
|
+
end
|
29
38
|
end
|
30
|
-
end
|
31
39
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
40
|
+
describe ".attributes" do
|
41
|
+
it "returns an array of attribute names as symbols" do
|
42
|
+
expect(User.attributes).to eq([:id, :paid, :name, :created_at, :profile, :reward_points])
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
describe ".attribute_defaults" do
|
47
|
+
it "returns a hash of attributes that have non-nil defaults" do
|
48
|
+
expect(User.attribute_defaults).to eq({reward_points: 0})
|
49
|
+
end
|
39
50
|
end
|
40
51
|
end
|
41
52
|
|
@@ -295,6 +306,12 @@ RSpec.describe "a class using ModelAttribute" do
|
|
295
306
|
end
|
296
307
|
end
|
297
308
|
|
309
|
+
describe 'a defaulted attribute (reward_points)' do
|
310
|
+
it "returns the default when unset" do
|
311
|
+
expect(user.reward_points).to eq(0)
|
312
|
+
end
|
313
|
+
end
|
314
|
+
|
298
315
|
describe "#write_attribute" do
|
299
316
|
it "does the same casting as using the writer method" do
|
300
317
|
user.write_attribute(:id, '3')
|
@@ -319,6 +336,12 @@ RSpec.describe "a class using ModelAttribute" do
|
|
319
336
|
expect(user.read_attribute(:id)).to be_nil
|
320
337
|
end
|
321
338
|
|
339
|
+
context "for an attribute with a default" do
|
340
|
+
it "returns the default if the attribute has not been set" do
|
341
|
+
expect(user.read_attribute(:reward_points)).to eq(0)
|
342
|
+
end
|
343
|
+
end
|
344
|
+
|
322
345
|
it "raises an error if passed an invalid attribute name" do
|
323
346
|
expect do
|
324
347
|
user.read_attribute(:spelling_mistake)
|
@@ -330,7 +353,7 @@ RSpec.describe "a class using ModelAttribute" do
|
|
330
353
|
describe "#changes" do
|
331
354
|
let(:changes) { user.changes }
|
332
355
|
|
333
|
-
context "for a model instance created with no attributes" do
|
356
|
+
context "for a model instance created with no attributes except defaults" do
|
334
357
|
it "is empty" do
|
335
358
|
expect(changes).to be_empty
|
336
359
|
end
|
@@ -408,7 +431,7 @@ RSpec.describe "a class using ModelAttribute" do
|
|
408
431
|
end
|
409
432
|
end
|
410
433
|
|
411
|
-
describe "id_changed?" do
|
434
|
+
describe "#id_changed?" do
|
412
435
|
context "with no changes" do
|
413
436
|
it "returns false" do
|
414
437
|
expect(user.id_changed?).to eq(false)
|
@@ -470,8 +493,18 @@ RSpec.describe "a class using ModelAttribute" do
|
|
470
493
|
expect(user.attributes_for_json).to include("profile" => json)
|
471
494
|
end
|
472
495
|
|
473
|
-
it "omits attributes
|
474
|
-
expect(user.attributes_for_json).to_not include("name")
|
496
|
+
it "omits attributes still set to the default value" do
|
497
|
+
expect(user.attributes_for_json).to_not include("name", "reward_points")
|
498
|
+
end
|
499
|
+
|
500
|
+
it "includes an attribute changed from its default value" do
|
501
|
+
user.name = "Fred"
|
502
|
+
expect(user.attributes_for_json).to include("name" => "Fred")
|
503
|
+
end
|
504
|
+
|
505
|
+
it "includes an attribute changed from its default value to nil" do
|
506
|
+
user.reward_points = nil
|
507
|
+
expect(user.attributes_for_json).to include("reward_points" => nil)
|
475
508
|
end
|
476
509
|
end
|
477
510
|
|
@@ -531,12 +564,16 @@ RSpec.describe "a class using ModelAttribute" do
|
|
531
564
|
expect(user.inspect).to include('profile: {"interests"=>["coding", "social networks"], "rank"=>15}')
|
532
565
|
end
|
533
566
|
|
567
|
+
it "includes defaulted attributes" do
|
568
|
+
expect(user.inspect).to include('reward_points: 0')
|
569
|
+
end
|
570
|
+
|
534
571
|
it "includes the class name" do
|
535
572
|
expect(user.inspect).to include("User")
|
536
573
|
end
|
537
574
|
|
538
575
|
it "looks like '#<User id: 1, paid: true, name: ..., created_at: ...>'" do
|
539
|
-
expect(user.inspect).to eq("#<User id: 1, paid: true, name: \"Fred\", created_at: 2014-12-25 08:00:00 +0000, profile: {\"interests\"=>[\"coding\", \"social networks\"], \"rank\"=>15}>")
|
576
|
+
expect(user.inspect).to eq("#<User id: 1, paid: true, name: \"Fred\", created_at: 2014-12-25 08:00:00 +0000, profile: {\"interests\"=>[\"coding\", \"social networks\"], \"rank\"=>15}, reward_points: 0>")
|
540
577
|
end
|
541
578
|
end
|
542
579
|
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: model_attribute
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- David Waller
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-04-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -94,21 +94,8 @@ dependencies:
|
|
94
94
|
- - ~>
|
95
95
|
- !ruby/object:Gem::Version
|
96
96
|
version: '4.3'
|
97
|
-
-
|
98
|
-
|
99
|
-
requirement: !ruby/object:Gem::Requirement
|
100
|
-
requirements:
|
101
|
-
- - ! '>='
|
102
|
-
- !ruby/object:Gem::Version
|
103
|
-
version: '0'
|
104
|
-
type: :development
|
105
|
-
prerelease: false
|
106
|
-
version_requirements: !ruby/object:Gem::Requirement
|
107
|
-
requirements:
|
108
|
-
- - ! '>='
|
109
|
-
- !ruby/object:Gem::Version
|
110
|
-
version: '0'
|
111
|
-
description:
|
97
|
+
description: ! " Attributes for non-ActiveRecord models.\n Smaller and simpler
|
98
|
+
than Virtus, and adds dirty tracking.\n"
|
112
99
|
email:
|
113
100
|
- dwaller@yammer-inc.com
|
114
101
|
executables: []
|
@@ -117,6 +104,7 @@ extra_rdoc_files: []
|
|
117
104
|
files:
|
118
105
|
- .gitignore
|
119
106
|
- .rspec
|
107
|
+
- .travis.yml
|
120
108
|
- CHANGELOG.md
|
121
109
|
- Gemfile
|
122
110
|
- Guardfile
|
@@ -124,8 +112,8 @@ files:
|
|
124
112
|
- README.md
|
125
113
|
- Rakefile
|
126
114
|
- lib/model_attribute.rb
|
115
|
+
- lib/model_attribute/casts.rb
|
127
116
|
- lib/model_attribute/errors.rb
|
128
|
-
- lib/model_attribute/json.rb
|
129
117
|
- lib/model_attribute/version.rb
|
130
118
|
- model_attribute.gemspec
|
131
119
|
- performance_comparison.rb
|
data/lib/model_attribute/json.rb
DELETED
@@ -1,27 +0,0 @@
|
|
1
|
-
module ModelAttribute
|
2
|
-
module Json
|
3
|
-
class << self
|
4
|
-
def valid?(value)
|
5
|
-
(value == nil ||
|
6
|
-
value == true ||
|
7
|
-
value == false ||
|
8
|
-
value.is_a?(Numeric) ||
|
9
|
-
value.is_a?(String) ||
|
10
|
-
(value.is_a?(Array) && valid_array?(value)) ||
|
11
|
-
(value.is_a?(Hash) && valid_hash?(value) ))
|
12
|
-
end
|
13
|
-
|
14
|
-
private
|
15
|
-
|
16
|
-
def valid_array?(array)
|
17
|
-
array.all? { |value| valid?(value) }
|
18
|
-
end
|
19
|
-
|
20
|
-
def valid_hash?(hash)
|
21
|
-
hash.all? do |key, value|
|
22
|
-
key.is_a?(String) && valid?(value)
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|