acts_as_replaceable 1.3.1 → 1.4.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,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: a57f730f9d08ae246d17fb2a676d682a852a3349
4
- data.tar.gz: f149a43c73d15bd6785f72d142de3a0b77a4c36a
2
+ SHA256:
3
+ metadata.gz: b4526faf0dc0b0551b77c00fafaeb9573eb6c7400f01bac6f631cc1c2a3f9518
4
+ data.tar.gz: 311de513a27c4a63f83f208d3803ebed1f1744a601a313158e1b352e596f6c6a
5
5
  SHA512:
6
- metadata.gz: fdd162a3dbc9f54a0fc784e374f75a20249a5ac6c39bc0a182e81b5b4ec41140fb72aeb85340699d3fefc241b4527f9af796098bf879c4f961b25c375171c027
7
- data.tar.gz: 9bceccadf52afb97451d77d7d313ea0c48d36dce68759b589bc536046c044d2b2cd444c8c0c1b118b12b814ef01a62f0e9c1f88a3e54d92d2d01e293337cd41a
6
+ metadata.gz: 7b35c9353693d4a8b3cadfc07d6f737e27a026bb3dc5d2e3e40044a1a9c67d48efed60b46e9f9e699a3e1ecc41bd20f5f5ce9a9d57885faca0f5015a91136713
7
+ data.tar.gz: b5f3f298c8ccad2efbd3fdb5905136363078bdb065a395dfb82193c92cabff17ee127d0277db659126842ffe2e89edfcb814a87c976227f1e78d3f55f1b77955
@@ -1,4 +1,4 @@
1
- require 'digest'
1
+ require 'openssl'
2
2
  require 'timeout'
3
3
 
4
4
  module ActsAsReplaceable
@@ -40,6 +40,10 @@ module ActsAsReplaceable
40
40
 
41
41
  module HelperMethods
42
42
  def self.sanitize_attribute_names(klass, *args)
43
+ unless klass.table_exists?
44
+ ActiveRecord::Base.logger.warn "(acts_as_replaceable) table `#{klass.table_name}` does not exist so excluding all attribute names"
45
+ return []
46
+ end
43
47
  # Intersect the proposed attributes with the column names so we don't start assigning attributes that don't exist. e.g. if the model doesn't have timestamps
44
48
  klass.column_names & args.flatten.compact.collect(&:to_s)
45
49
  end
@@ -64,6 +68,8 @@ module ActsAsReplaceable
64
68
  sql << "#{attribute_name} IS NULL"
65
69
  end
66
70
  end
71
+
72
+ return nil if sql.empty?
67
73
  return [sql.join(' AND ')] + binds
68
74
  end
69
75
 
@@ -86,7 +92,7 @@ module ActsAsReplaceable
86
92
 
87
93
  # Searches the database for an existing copies of record
88
94
  def self.find_existing(record)
89
- existing = record.class
95
+ existing = record.class.default_scoped
90
96
  existing = existing.where match_conditions(record)
91
97
  existing = existing.where insensitive_match_conditions(record)
92
98
  end
@@ -104,7 +110,7 @@ module ActsAsReplaceable
104
110
  # eg. In a multi-threaded environment, 'find_or_create' is prone to failure due to the possibility
105
111
  # that the process is preempted between the 'find' and 'create' logic
106
112
  def self.lock(record, timeout = 20)
107
- lock_id = "ActsAsReplaceable/#{Digest::MD5.digest([match_conditions(record), insensitive_match_conditions(record)].inspect)}"
113
+ lock_id = "ActsAsReplaceable/#{OpenSSL::Digest::MD5.digest([match_conditions(record), insensitive_match_conditions(record)].inspect)}"
108
114
  acquired = false
109
115
 
110
116
  # Acquire the lock by atomically incrementing and returning the value to see if we're first
@@ -175,6 +181,14 @@ module ActsAsReplaceable
175
181
  # Inherit target's attributes for those in acts_as_replaceable_options[:inherit]
176
182
  ActsAsReplaceable::HelperMethods.copy_attributes(acts_as_replaceable_options[:inherit], existing, self)
177
183
 
184
+ # Rails 5 introduced AR::Dirty and started using `mutations_from_database` to
185
+ # lookup `id_in_database` which is required for the `_update_record` call
186
+ #
187
+ # This chunk of code is copied from https://api.rubyonrails.org/classes/ActiveRecord/Persistence.html#method-i-becomes
188
+ if existing.respond_to?(:mutations_from_database, true)
189
+ instance_variable_set("@mutations_from_database", existing.send(:mutations_from_database) || nil)
190
+ end
191
+
178
192
  @new_record = false
179
193
  @has_been_replaced = true
180
194
  @has_not_changed = !ActsAsReplaceable::HelperMethods.mark_changes(self, existing)
@@ -1,6 +1,6 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe 'acts_as_dag' do
3
+ describe 'acts_as_replaceable' do
4
4
  before(:each) do
5
5
  [Material, Item, Person].each(&:destroy_all) # Because we're using sqlite3 and it doesn't support transactional specs (afaik)
6
6
  end
@@ -14,6 +14,16 @@ describe 'acts_as_dag' do
14
14
  end
15
15
  end
16
16
 
17
+ describe "Model" do
18
+ it 'evaluates without error when no database table exists' do
19
+ eval("class NoTable < ActiveRecord::Base; end")
20
+ klass = NoTable
21
+
22
+ klass.table_name = "some_table_that_does_not_exist"
23
+ expect(klass.acts_as_replaceable).to be_nil
24
+ end
25
+ end
26
+
17
27
  describe "Helper Methods" do
18
28
  before(:each) { @record = insert_model(Material, :name => 'glass')}
19
29
 
@@ -109,6 +119,12 @@ describe 'acts_as_dag' do
109
119
  Person.where(:first_name => 'John').count.should == 1
110
120
  end
111
121
 
122
+ it "should correctly detect difference between blank and nil values" do
123
+ a = Person.create! :first_name => 'John', :last_name => ''
124
+ a = Person.create! :first_name => 'John', :last_name => nil
125
+ Person.where(:first_name => 'John').count.should == 2
126
+ end
127
+
112
128
  it "should inherit the id of the existing record" do
113
129
  a = Material.create! :name => 'wood'
114
130
  b = Material.create! :name => 'wood'
data/spec/spec_helper.rb CHANGED
@@ -3,6 +3,7 @@ $LOAD_PATH << File.join(File.dirname(__FILE__), '..', 'lib')
3
3
  require 'active_record'
4
4
  require 'logger'
5
5
  require 'acts_as_replaceable'
6
+ require 'byebug'
6
7
 
7
8
  ActiveRecord::Base.logger = Logger.new(STDOUT)
8
9
  ActiveRecord::Base.logger.level = Logger::INFO
metadata CHANGED
@@ -1,15 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: acts_as_replaceable
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.1
4
+ version: 1.4.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nicholas Jakobsen
8
8
  - Ryan Wallace
9
- autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2014-07-09 00:00:00.000000000 Z
11
+ date: 2026-04-24 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: rails
@@ -17,63 +16,48 @@ dependencies:
17
16
  requirements:
18
17
  - - ">="
19
18
  - !ruby/object:Gem::Version
20
- version: 4.0.6
19
+ version: 4.1.8
21
20
  - - "<"
22
21
  - !ruby/object:Gem::Version
23
- version: 4.3.0
22
+ version: '9'
24
23
  type: :runtime
25
24
  prerelease: false
26
25
  version_requirements: !ruby/object:Gem::Requirement
27
26
  requirements:
28
27
  - - ">="
29
28
  - !ruby/object:Gem::Version
30
- version: 4.0.6
29
+ version: 4.1.8
31
30
  - - "<"
32
31
  - !ruby/object:Gem::Version
33
- version: 4.3.0
34
- - !ruby/object:Gem::Dependency
35
- name: bundler
36
- requirement: !ruby/object:Gem::Requirement
37
- requirements:
38
- - - "~>"
39
- - !ruby/object:Gem::Version
40
- version: '1.5'
41
- type: :development
42
- prerelease: false
43
- version_requirements: !ruby/object:Gem::Requirement
44
- requirements:
45
- - - "~>"
46
- - !ruby/object:Gem::Version
47
- version: '1.5'
32
+ version: '9'
48
33
  - !ruby/object:Gem::Dependency
49
34
  name: sqlite3
50
35
  requirement: !ruby/object:Gem::Requirement
51
36
  requirements:
52
- - - "~>"
37
+ - - ">="
53
38
  - !ruby/object:Gem::Version
54
- version: '1.3'
39
+ version: '0'
55
40
  type: :development
56
41
  prerelease: false
57
42
  version_requirements: !ruby/object:Gem::Requirement
58
43
  requirements:
59
- - - "~>"
44
+ - - ">="
60
45
  - !ruby/object:Gem::Version
61
- version: '1.3'
46
+ version: '0'
62
47
  - !ruby/object:Gem::Dependency
63
48
  name: rspec-rails
64
49
  requirement: !ruby/object:Gem::Requirement
65
50
  requirements:
66
- - - "~>"
51
+ - - ">="
67
52
  - !ruby/object:Gem::Version
68
- version: '2.0'
53
+ version: '0'
69
54
  type: :development
70
55
  prerelease: false
71
56
  version_requirements: !ruby/object:Gem::Requirement
72
57
  requirements:
73
- - - "~>"
58
+ - - ">="
74
59
  - !ruby/object:Gem::Version
75
- version: '2.0'
76
- description:
60
+ version: '0'
77
61
  email: technical@rrnpilot.org
78
62
  executables: []
79
63
  extensions: []
@@ -87,7 +71,6 @@ files:
87
71
  homepage: http://github.com/rrn/acts_as_replaceable
88
72
  licenses: []
89
73
  metadata: {}
90
- post_install_message:
91
74
  rdoc_options: []
92
75
  require_paths:
93
76
  - lib
@@ -102,9 +85,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
102
85
  - !ruby/object:Gem::Version
103
86
  version: '0'
104
87
  requirements: []
105
- rubyforge_project:
106
- rubygems_version: 2.4.7
107
- signing_key:
88
+ rubygems_version: 3.7.2
108
89
  specification_version: 4
109
90
  summary: Overloads the create_or_update_without_callbacks method to allow duplicate
110
91
  records to be replaced without needing to always use find_or_create_by.