active_record-acts_as 2.2.1 → 2.3.0

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,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