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 CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- ODkyMGNiNzY1MDY3MGY1YjBhMTQ1YTQ5Mjk3NWZmNmIwMDVmZWI3Mg==
4
+ MmZjNzAyYWJjNWQyZmJmZDQxNDgwYTgyMTU0MTViZjRiY2U2NmM5OQ==
5
5
  data.tar.gz: !binary |-
6
- YjAzYjJkNWQ2YjIyZTIwOThmYjY5ZTRhNzJkOWZkZGZmNzlmMmY3Mg==
6
+ Mzk1MjM1MTZhNDcyMTNlY2I2OTMzZTljOTU1NWJmMmU5MTE4Yjg3NQ==
7
7
  !binary "U0hBNTEy":
8
8
  metadata.gz: !binary |-
9
- YzgxZTFkNWI1NGUzZWYzNDk2NTQ1NjhlYWYzNmZiMzAwNmEyYjE2MWUxYTU3
10
- YTc5MDRlYjZhZDBmZmQ0YTUzOGNmNTM4NDViMzliMDQ4MmZhZGE3NjUxZDIy
11
- NjJjYWNhZWM0ODYwODg5ZTEzNGVjYWZjNTVlYjIzY2JiNTNjY2Q=
9
+ OWI4ZWFhZDljMDNhMjgzYWVkNTQ5NDVhZmMzMjhmN2JhMTdiNDNlZjVkZjc4
10
+ NjNmNDRjMDg3MmJiMTg1YThiN2YzNTMwMTBhMGQxMGYxMGMzZWFhZmQ2MjU2
11
+ N2YwMDhlZjg1NTU2NzI5YTc0NmUzNWZhNTBmOTdhY2NiNDg1N2E=
12
12
  data.tar.gz: !binary |-
13
- NTdjYmNjZTQ1ZDVjYmM5NGZmNmRmN2M3NjhjNjJjZWU4MTljOWE1YjJmZmY4
14
- YTg4NzgxNmI0YWQzOTljZGJlNjUzNzI5NDI2NzMxNjI3Mzk4MTNjMDNkOGNi
15
- YTQ1ZGExNjU0OGRiZWJmYzNlZTM1ZDY5NWMwNTQxNWViZGNmMTM=
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
- attr_accessor :fullname, :email
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
- @data[method.to_s.chomp('=').to_sym] = args.first
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
@@ -1,3 +1,3 @@
1
1
  module Her
2
- VERSION = "0.5"
2
+ VERSION = "0.5.1"
3
3
  end
@@ -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
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: her
3
3
  version: !ruby/object:Gem::Version
4
- version: '0.5'
4
+ version: 0.5.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Rémi Prévost