her 0.5 → 0.5.1
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 +8 -8
- data/README.md +24 -1
- data/lib/her/model/orm.rb +32 -1
- data/lib/her/version.rb +1 -1
- data/spec/model/orm_spec.rb +59 -0
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
MmZjNzAyYWJjNWQyZmJmZDQxNDgwYTgyMTU0MTViZjRiY2U2NmM5OQ==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
Mzk1MjM1MTZhNDcyMTNlY2I2OTMzZTljOTU1NWJmMmU5MTE4Yjg3NQ==
|
7
7
|
!binary "U0hBNTEy":
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
OWI4ZWFhZDljMDNhMjgzYWVkNTQ5NDVhZmMzMjhmN2JhMTdiNDNlZjVkZjc4
|
10
|
+
NjNmNDRjMDg3MmJiMTg1YThiN2YzNTMwMTBhMGQxMGYxMGMzZWFhZmQ2MjU2
|
11
|
+
N2YwMDhlZjg1NTU2NzI5YTc0NmUzNWZhNTBmOTdhY2NiNDg1N2E=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
ZDY3NzU2MmFhZTJjN2I3MWQ1ODgzNGYyZTAwMDZhNTlhYTdmYTNkMjNjOWFi
|
14
|
+
MjMzMjliMjMxNWY1NGRlNzBmZDMxYTQ1YjIwMjgzOTg5NGRkM2MzNzhjNDRk
|
15
|
+
ZmJiYzdmZWE4YjA0ZGJmMTIxOTc3ZjNkMmUyMmI2NGZkODRhYzY=
|
data/README.md
CHANGED
@@ -350,7 +350,7 @@ However, validations must be triggered manually — they are not run, for exampl
|
|
350
350
|
class User
|
351
351
|
include Her::Model
|
352
352
|
|
353
|
-
|
353
|
+
attributes :fullname, :email
|
354
354
|
validates :fullname, :presence => true
|
355
355
|
validates :email, :presence => true
|
356
356
|
end
|
@@ -362,6 +362,29 @@ end
|
|
362
362
|
# POST /users&fullname=Tobias+Fünke will still be called, even if the user is not valid
|
363
363
|
```
|
364
364
|
|
365
|
+
### Dirty attributes
|
366
|
+
|
367
|
+
Her includes `ActiveModel::Dirty` so you can keep track of the attributes that have changed in an object.
|
368
|
+
an object, or `#create` on a model class.
|
369
|
+
|
370
|
+
```ruby
|
371
|
+
class User
|
372
|
+
include Her::Model
|
373
|
+
|
374
|
+
attributes :fullname, :email
|
375
|
+
end
|
376
|
+
|
377
|
+
@user = User.new(:fullname => "Tobias Fünke")
|
378
|
+
@user.fullname_changed? # => true
|
379
|
+
@user.changes # => { :fullname => [nil, "Tobias Fünke"] }
|
380
|
+
|
381
|
+
@user.save
|
382
|
+
# POST /users&fullname=Tobias+Fünke
|
383
|
+
|
384
|
+
@user.fullname_changed? # => false
|
385
|
+
@user.changes # => {}
|
386
|
+
```
|
387
|
+
|
365
388
|
### Callbacks
|
366
389
|
|
367
390
|
You can add *before* and *after* callbacks to your models that are triggered on specific actions. You can use symbols or blocks.
|
data/lib/her/model/orm.rb
CHANGED
@@ -50,7 +50,8 @@ module Her
|
|
50
50
|
# @private
|
51
51
|
def method_missing(method, *args, &blk)
|
52
52
|
if method.to_s.end_with?('=')
|
53
|
-
|
53
|
+
attribute = method.to_s.chomp('=').to_sym
|
54
|
+
@data[attribute] = args.first
|
54
55
|
elsif method.to_s.end_with?('?')
|
55
56
|
@data.include?(method.to_s.chomp('?').to_sym)
|
56
57
|
elsif @data.include?(method)
|
@@ -65,6 +66,10 @@ module Her
|
|
65
66
|
method.to_s.end_with?('=') || method.to_s.end_with?('?') || @data.include?(method) || super
|
66
67
|
end
|
67
68
|
|
69
|
+
def respond_to_missing?(method, include_private = false)
|
70
|
+
method.to_s.end_with?('=') || method.to_s.end_with?('?') || @data.include?(method) || @data.include?(method) || super
|
71
|
+
end
|
72
|
+
|
68
73
|
# Assign new data to an instance
|
69
74
|
def assign_data(new_data)
|
70
75
|
new_data = Her::Model::ORM.use_setter_methods(self, new_data)
|
@@ -145,6 +150,7 @@ module Her
|
|
145
150
|
update_data(self.class.parse(parsed_data[:data])) if parsed_data[:data].any?
|
146
151
|
self.metadata = parsed_data[:metadata]
|
147
152
|
self.response_errors = parsed_data[:errors]
|
153
|
+
self.changed_attributes.clear if self.changed_attributes.present?
|
148
154
|
|
149
155
|
return false if self.response_errors.any?
|
150
156
|
end
|
@@ -204,6 +210,30 @@ module Her
|
|
204
210
|
Her::Model::ORM.initialize_collection(self, parsed_data)
|
205
211
|
end
|
206
212
|
|
213
|
+
# Define the attributes that will be used to track dirty attributes and validations
|
214
|
+
#
|
215
|
+
# @param [Array] attributes
|
216
|
+
def attributes(*attributes)
|
217
|
+
define_attribute_methods attributes
|
218
|
+
|
219
|
+
attributes.each do |attribute|
|
220
|
+
attribute = attribute.to_sym
|
221
|
+
|
222
|
+
define_method "#{attribute}".to_sym do
|
223
|
+
@data.include?(attribute) ? @data[attribute] : nil
|
224
|
+
end
|
225
|
+
|
226
|
+
define_method "#{attribute}=".to_sym do |value|
|
227
|
+
self.send("#{attribute}_will_change!".to_sym) if @data[attribute] != value
|
228
|
+
@data[attribute] = value
|
229
|
+
end
|
230
|
+
|
231
|
+
define_method "#{attribute}?".to_sym do
|
232
|
+
@data.include?(attribute)
|
233
|
+
end
|
234
|
+
end
|
235
|
+
end
|
236
|
+
|
207
237
|
# Parse data before assigning it to a resource
|
208
238
|
#
|
209
239
|
# @param [Hash] data
|
@@ -272,6 +302,7 @@ module Her
|
|
272
302
|
update_data(data)
|
273
303
|
@metadata = parsed_data[:metadata]
|
274
304
|
@response_errors = parsed_data[:errors]
|
305
|
+
@changed_attributes.clear if @changed_attributes.present?
|
275
306
|
end
|
276
307
|
end
|
277
308
|
end
|
data/lib/her/version.rb
CHANGED
data/spec/model/orm_spec.rb
CHANGED
@@ -464,6 +464,65 @@ describe Her::Model::ORM do
|
|
464
464
|
end
|
465
465
|
end
|
466
466
|
|
467
|
+
context "checking dirty attributes" do
|
468
|
+
before do
|
469
|
+
Her::API.setup :url => "https://api.example.com" do |builder|
|
470
|
+
builder.use Her::Middleware::FirstLevelParseJSON
|
471
|
+
builder.use Faraday::Request::UrlEncoded
|
472
|
+
builder.adapter :test do |stub|
|
473
|
+
stub.get("/users/1") { |env| [200, {}, { :id => 1, :fullname => "Lindsay Fünke" }.to_json] }
|
474
|
+
stub.put("/users/1") { |env| [200, {}, { :id => 1, :fullname => "Tobias Fünke" }.to_json] }
|
475
|
+
stub.post("/users") { |env| [200, {}, { :id => 1, :fullname => "Tobias Fünke" }.to_json] }
|
476
|
+
end
|
477
|
+
end
|
478
|
+
|
479
|
+
spawn_model "Foo::User" do
|
480
|
+
attributes :fullname, :email
|
481
|
+
end
|
482
|
+
end
|
483
|
+
|
484
|
+
context "for existing resource" do
|
485
|
+
it "tracks dirty attributes" do
|
486
|
+
user = Foo::User.find(1)
|
487
|
+
user.fullname = "Tobias Fünke"
|
488
|
+
user.fullname_changed?.should be_true
|
489
|
+
user.email_changed?.should be_false
|
490
|
+
user.should be_changed
|
491
|
+
user.save
|
492
|
+
user.should_not be_changed
|
493
|
+
end
|
494
|
+
end
|
495
|
+
|
496
|
+
context "for new resource" do
|
497
|
+
it "tracks dirty attributes" do
|
498
|
+
user = Foo::User.new
|
499
|
+
user.fullname = "Tobias Fünke"
|
500
|
+
user.fullname_changed?.should be_true
|
501
|
+
user.should be_changed
|
502
|
+
user.save
|
503
|
+
user.should_not be_changed
|
504
|
+
end
|
505
|
+
end
|
506
|
+
end
|
507
|
+
|
508
|
+
context "validating attributes" do
|
509
|
+
before do
|
510
|
+
spawn_model "Foo::User" do
|
511
|
+
attributes :fullname, :email
|
512
|
+
validates_presence_of :fullname
|
513
|
+
validates_presence_of :email
|
514
|
+
end
|
515
|
+
end
|
516
|
+
|
517
|
+
it "validates attributes when calling #valid?" do
|
518
|
+
user = Foo::User.new
|
519
|
+
user.should_not be_valid
|
520
|
+
user.fullname = "Tobias Fünke"
|
521
|
+
user.email = "tobias@bluthcompany.com"
|
522
|
+
user.should be_valid
|
523
|
+
end
|
524
|
+
end
|
525
|
+
|
467
526
|
context "when include_root_in_json is true" do
|
468
527
|
context "when include_root_in_json is true" do
|
469
528
|
before do
|