active_record-acts_as 2.2.1 → 2.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 343f5f0ec73829580cfedcf39acaf118c672a73b
4
- data.tar.gz: 07f06e2d9e8102b00030627222b2c9781593396b
3
+ metadata.gz: 003f08a2aa83c2fbd3b38d573f53b0a54b2f08f4
4
+ data.tar.gz: 9fc859b6b9a7a6139950d6f33d5aaaae767ba61b
5
5
  SHA512:
6
- metadata.gz: 6e48b05426332a971ab3b175178ff758ff5a67b38892f1e98c101eb23cdbbc5ae5543b7ed29ff50af4708a03ec2a0ac446547dd7469080b24d7306d28449c13d
7
- data.tar.gz: f642986b3c589b62663b94641abd58aacb1260e1ae85bc237ab3ef539e6572eb17bee0096989ab6f78ccc1b490ec9012b6532196915bbd880105a467c09937d3
6
+ metadata.gz: 62fcb7cd4f2a32c18375409f47afa2cdcd2478f1cc56954dd1e5b8910e7414b6d5eb6cd9c02455827a5cfdcb355afec05bcb3c0730df85c7f29a5bec884ee228
7
+ data.tar.gz: cbd963f8a2b48ec52fe2763ff966f14fd110335d6f64d5a537761a755c5a4a4be31143cf74b5d745c2a0a8078006998c35b628c0abb7402d50114aaaa017b6e4
data/CHANGELOG.md CHANGED
@@ -4,6 +4,10 @@ All notable changes to this project will be documented in this file.
4
4
  The format is based on [Keep a Changelog](http://keepachangelog.com/)
5
5
  and this project adheres to [Semantic Versioning](http://semver.org/).
6
6
 
7
+ ## [2.2.1] - 2017-04-08
8
+ ### Fixed
9
+ - Make sure submodel instance changes are retained when calling `submodel_instance.acting_as.specific`
10
+
7
11
  ## [2.2.0] - 2017-04-08
8
12
  ### Added
9
13
  - Added support for calling superclass methods on the subclass or subclass relations
@@ -65,7 +69,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
65
69
  ### Fixed
66
70
  - Fixed `remove_actable` migration helper (https://github.com/hzamani/active_record-acts_as/pull/71, thanks to [nuclearpidgeon](https://github.com/nuclearpidgeon)!)
67
71
 
68
- [Unreleased]: https://github.com/krautcomputing/active_record-acts_as/compare/v2.2.0...HEAD
72
+ [Unreleased]: https://github.com/krautcomputing/active_record-acts_as/compare/v2.2.1...HEAD
73
+ [2.2.1]: https://github.com/krautcomputing/active_record-acts_as/compare/v2.2.0...v2.2.1
69
74
  [2.2.0]: https://github.com/krautcomputing/active_record-acts_as/compare/v2.1.1...v2.2.0
70
75
  [2.1.1]: https://github.com/krautcomputing/active_record-acts_as/compare/v2.1.0...v2.1.1
71
76
  [2.1.0]: https://github.com/krautcomputing/active_record-acts_as/compare/v2.0.9...v2.1.0
@@ -14,11 +14,9 @@ module ActiveRecord
14
14
  end
15
15
 
16
16
  def actable_must_be_valid
17
- if validates_actable
18
- unless acting_as.valid?
19
- acting_as.errors.each do |att, message|
20
- errors.add(att, message)
21
- end
17
+ unless acting_as.valid?
18
+ acting_as.errors.each do |attribute, message|
19
+ errors.add(attribute, message) unless errors[attribute].include?(message)
22
20
  end
23
21
  end
24
22
  end
@@ -82,7 +80,9 @@ module ActiveRecord
82
80
  end
83
81
 
84
82
  def touch(*args)
85
- acting_as.touch(*args) if acting_as.persisted?
83
+ self_args, acting_as_args = args.partition { |arg| has_attribute?(arg, true) }
84
+ super(*self_args) if self_args.any?
85
+ acting_as.touch(*acting_as_args) if acting_as.persisted?
86
86
  end
87
87
 
88
88
  def respond_to?(name, include_private = false, as_original_class = false)
@@ -6,14 +6,15 @@ module ActiveRecord
6
6
  module ClassMethods
7
7
  def acts_as(name, scope = nil, options = {})
8
8
  options, scope = scope, nil if Hash === scope
9
+
9
10
  association_method = options.delete(:association_method)
10
- touch = options.delete(:touch)
11
- as = options.delete(:as) || :actable
12
- options = options.reverse_merge(as: as, validate: false, autosave: true, inverse_of: as)
11
+ touch = options.delete(:touch)
12
+ as = options.delete(:as) || :actable
13
+ validates_actable = !options.key?(:validates_actable) || options.delete(:validates_actable)
13
14
 
14
- cattr_reader(:validates_actable) { options.delete(:validates_actable) == false ? false : true }
15
+ options = options.reverse_merge(as: as, validate: false, autosave: true, inverse_of: as)
15
16
 
16
- reflections = has_one name, scope, options
17
+ reflections = has_one(name, scope, options)
17
18
  default_scope -> {
18
19
  case association_method
19
20
  when :eager_load
@@ -24,7 +25,7 @@ module ActiveRecord
24
25
  includes(name)
25
26
  end
26
27
  }
27
- validate :actable_must_be_valid
28
+ validate :actable_must_be_valid if validates_actable
28
29
 
29
30
  unless touch == false
30
31
  after_update :touch, if: :changed?
@@ -78,7 +79,7 @@ module ActiveRecord
78
79
  def actable(options = {})
79
80
  name = options.delete(:as) || :actable
80
81
 
81
- reflections = belongs_to(name, options.reverse_merge(polymorphic: true, dependent: :destroy, autosave: true, inverse_of: to_s.underscore))
82
+ reflections = belongs_to(name, options.reverse_merge(validate: false, polymorphic: true, dependent: :destroy, autosave: true, inverse_of: to_s.underscore))
82
83
 
83
84
  cattr_reader(:actable_reflection) { reflections.stringify_keys[name.to_s] }
84
85
 
@@ -1,6 +1,6 @@
1
1
  module ActiveRecord
2
2
  module ActsAs
3
- VERSION = "2.2.1"
3
+ VERSION = "2.3.0"
4
4
  end
5
5
  end
6
6
 
data/spec/acts_as_spec.rb CHANGED
@@ -190,6 +190,7 @@ RSpec.describe "ActiveRecord::Base model with #acts_as called" do
190
190
  "pen_collection_id": null,
191
191
  "settings": {"global_option":"globalvalue", "option1":"value1"},
192
192
  "color": "red",
193
+ "designed_at": null,
193
194
  "created_at": ' + pen.created_at.to_json + ',
194
195
  "updated_at": ' + pen.updated_at.to_json + '
195
196
  }
@@ -218,46 +219,56 @@ RSpec.describe "ActiveRecord::Base model with #acts_as called" do
218
219
  end
219
220
  end
220
221
 
221
- context "touching" do
222
- it "forwards arguments to #touch to the supermodel" do
223
- pen.save!
224
- expect(pen.product).to receive(:touch).with(:one, :two)
225
- pen.touch(:one, :two)
226
- end
227
-
228
- it "touches supermodel on save" do
229
- pen.save
230
- pen.reload
231
- update = pen.product.updated_at
232
- pen.color = "gray"
233
- pen.save
234
- expect(pen.updated_at).not_to eq(update)
235
- end
236
-
237
- it "touches supermodel only when attributes changed" do
238
- pen.save
222
+ context 'touching' do
223
+ describe '#touch with arguments' do
224
+ it "forwards supermodel arguments tothe supermodel" do
225
+ pen.save!
226
+ expect(pen.product).to receive(:touch).with(:updated_at)
227
+ pen.touch(:updated_at, :designed_at)
228
+ end
239
229
 
240
- expect { pen.save }.to_not change { pen.reload.product.updated_at }
230
+ it "updates submodel arguments" do
231
+ pen.save!
232
+ expect { pen.touch(:designed_at) }.to change { pen.designed_at }
233
+ end
241
234
  end
242
235
 
243
- it "touches supermodel when #touch is called" do
244
- pen.save
245
-
246
- expect { pen.touch }.to change { pen.product.updated_at }
236
+ describe '#touch without arguments' do
237
+ it "touches the supermodel" do
238
+ pen.save!
239
+ expect(pen.product).to receive(:touch).with(no_args)
240
+ pen.touch
241
+ end
247
242
  end
248
243
 
249
- it "touches belongs_to-touch associations if supermodel is updated" do
250
- pen.build_pen_collection
251
- pen.save!
252
- pen.name = "superpen"
253
- expect { pen.save! }.to change { pen.pen_collection.updated_at }
254
- end
255
-
256
- it "touches belongs_to-touch associations of supermodel when submodel is updated" do
257
- pen.store = store
258
- pen.save!
259
- pen.color = "gray"
260
- expect { pen.save! }.to change { pen.store.updated_at }
244
+ describe 'saving' do
245
+ it "touches supermodel on save" do
246
+ pen.save
247
+ pen.reload
248
+ update = pen.product.updated_at
249
+ pen.color = "gray"
250
+ pen.save
251
+ expect(pen.updated_at).not_to eq(update)
252
+ end
253
+
254
+ it "does not touch supermodel when no attributes changed" do
255
+ pen.save!
256
+ expect { pen.save! }.to_not change { pen.reload.product.updated_at }
257
+ end
258
+
259
+ it "touches belongs_to-touch associations if supermodel is updated" do
260
+ pen.build_pen_collection
261
+ pen.save!
262
+ pen.name = "superpen"
263
+ expect { pen.save! }.to change { pen.pen_collection.updated_at }
264
+ end
265
+
266
+ it "touches belongs_to-touch associations of supermodel when submodel is updated" do
267
+ pen.store = store
268
+ pen.save!
269
+ pen.color = "gray"
270
+ expect { pen.save! }.to change { pen.store.updated_at }
271
+ end
261
272
  end
262
273
  end
263
274
 
@@ -283,25 +294,42 @@ RSpec.describe "ActiveRecord::Base model with #acts_as called" do
283
294
  expect { Product.find(product_id) }.to raise_error(ActiveRecord::RecordNotFound)
284
295
  end
285
296
 
286
- context "validates supermodel attributes" do
287
- it "upon validate" do
288
- p = Pen.new
289
- expect(p).to be_invalid
290
- expect(p.errors.keys).to include(:name, :price, :color)
291
- p.name = 'testing'
292
- expect(p).to be_invalid
293
- p.color = 'red'
294
- expect(p).to be_invalid
295
- p.price = 0.8
296
- expect(p).to be_valid
297
+ context "errors" do
298
+ context 'when validates_actable is set to true' do
299
+ it "combines supermodel and submodel errors" do
300
+ pen = Pen.new
301
+ expect(pen).to be_invalid
302
+ expect(pen.errors.to_h).to eq(
303
+ name: "can't be blank",
304
+ price: "can't be blank",
305
+ color: "can't be blank"
306
+ )
307
+ pen.name = 'testing'
308
+ expect(pen).to be_invalid
309
+ expect(pen.errors.to_h).to eq(
310
+ price: "can't be blank",
311
+ color: "can't be blank"
312
+ )
313
+ pen.color = 'red'
314
+ expect(pen).to be_invalid
315
+ expect(pen.errors.to_h).to eq(
316
+ price: "can't be blank"
317
+ )
318
+ pen.price = 0.8
319
+ expect(pen).to be_valid
320
+ end
297
321
  end
298
322
 
299
- it "unless validates_actable is set to false" do
300
- p = IsolatedPen.new
301
- expect(p).to be_invalid
302
- expect(p.errors.keys).to include(:color)
303
- p.color = 'red'
304
- expect(p).to be_valid
323
+ context 'when validates_actable is set to false' do
324
+ it "unless validates_actable is set to false" do
325
+ pen = IsolatedPen.new
326
+ expect(pen).to be_invalid
327
+ expect(pen.errors.to_h).to eq(
328
+ color: "can't be blank"
329
+ )
330
+ pen.color = 'red'
331
+ expect(pen).to be_valid
332
+ end
305
333
  end
306
334
  end
307
335
 
@@ -346,6 +374,7 @@ RSpec.describe "ActiveRecord::Base model with #acts_as called" do
346
374
  "store_id" => nil,
347
375
  "settings" => {},
348
376
  "created_at" => nil,
377
+ "designed_at" => nil,
349
378
  "updated_at" => nil,
350
379
  "color" => "red",
351
380
  "pen_collection_id" => nil
@@ -355,7 +384,7 @@ RSpec.describe "ActiveRecord::Base model with #acts_as called" do
355
384
 
356
385
  describe "#attribute_names" do
357
386
  it "returns the attribute names of the supermodel and submodel" do
358
- expect(pen.attribute_names).to eq(["id", "color", "pen_collection_id", "name", "price", "store_id", "settings", "created_at", "updated_at"])
387
+ expect(pen.attribute_names).to eq(["id", "color", "designed_at", "pen_collection_id", "name", "price", "store_id", "settings", "created_at", "updated_at"])
359
388
  end
360
389
  end
361
390
 
data/spec/models.rb CHANGED
@@ -95,6 +95,7 @@ def initialize_schema
95
95
 
96
96
  create_table :pens do |t|
97
97
  t.string :color
98
+ t.datetime :designed_at
98
99
  t.integer :pen_collection_id
99
100
  end
100
101
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: active_record-acts_as
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.2.1
4
+ version: 2.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Hassan Zamani
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2017-04-08 00:00:00.000000000 Z
12
+ date: 2017-04-12 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: sqlite3