her 0.5 → 0.5.1

Sign up to get free protection for your applications and to get access to all the features.
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