active_record_upsert 0.7.4 → 0.8.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
  SHA256:
3
- metadata.gz: e867ac92d0f9da516a6845e3ebd2fc03da038ae5451e6ff0ce217cbf3e999423
4
- data.tar.gz: 0b559e347df791f257144798d12e03d882584af0035606ceba2777b1aa13c6da
3
+ metadata.gz: 5ebd4ad13239063f0e7108c42cb390feba52c688bf8ad4819f9a219d18d101a2
4
+ data.tar.gz: f6435a0f03792a85e2644690dac99ab7c0300288862febd5e2b35cb5f9bcf1fe
5
5
  SHA512:
6
- metadata.gz: 72680038d1f62c296972e56cd788fd01ddc17aec56590eda76b32d3d541543c3acd74e12b1a1ee716df7cbc4d7e148ef5afb34943824e68e55fc1115247621a7
7
- data.tar.gz: 0f4270bb398c42726fdec1494e6da82e08ccd73e51e384267cf109ba597ed9e36981922ac013cce7aad90b704222c11576cb07214f401161d4f5432fbdeee5a6
6
+ metadata.gz: 3f36a02374d2f9c65359fc3354700d2c219bdc0c31cdb9566057e12205433f49abc380f7b67b394974bfc46e519516d3efd9eb0a249847b4a2a7902fcfda55fe
7
+ data.tar.gz: 01698ff04fb0f5285b8a95fec88c3c1a132da383d3de4f13e450b841e21a2d255a24a6ec0490cb90eb95d66071bfe7faf6373a2b15ebca0d35e1bc3d13161e1c
data/Gemfile.base ADDED
@@ -0,0 +1,12 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
4
+
5
+ group :development, :test do
6
+ gem 'bundler', '>= 1.13'
7
+ gem 'database_cleaner', '~> 1.6'
8
+ gem 'pg', '~> 0.18'
9
+ gem 'pry', '> 0'
10
+ gem 'rake', '>= 10.0'
11
+ gem 'rspec', '>= 3.0', '< 4'
12
+ end
data/Gemfile.rails-5-0 ADDED
@@ -0,0 +1,5 @@
1
+ group :development, :test do
2
+ gem 'rails', '>= 5.0', '< 5.1'
3
+ end
4
+
5
+ eval_gemfile "#{__dir__}/Gemfile.base"
data/Gemfile.rails-5-1 ADDED
@@ -0,0 +1,5 @@
1
+ group :development, :test do
2
+ gem 'rails', '>= 5.1', '< 5.2'
3
+ end
4
+
5
+ eval_gemfile "#{__dir__}/Gemfile.base"
data/Gemfile.rails-5-2 ADDED
@@ -0,0 +1,5 @@
1
+ group :development, :test do
2
+ gem 'rails', '>= 5.2.0.rc1', '< 6.0'
3
+ end
4
+
5
+ eval_gemfile "#{__dir__}/Gemfile.base"
@@ -0,0 +1,5 @@
1
+ group :development, :test do
2
+ gem 'rails', github: 'rails/rails'
3
+ end
4
+
5
+ eval_gemfile "./Gemfile.base"
data/README.md CHANGED
@@ -140,6 +140,14 @@ r.upsert
140
140
  # => #<Vehicle id: 1, make: 'Ford', name: 'Focus', doors: 2>
141
141
  ```
142
142
 
143
+ Partial indexes can be supported with the addition of a `where` clause.
144
+
145
+ ```ruby
146
+ class Account < ApplicationRecord
147
+ upsert_keys :name, where: 'active is TRUE'
148
+ end
149
+ ```
150
+
143
151
  ## Tests
144
152
 
145
153
  Make sure to have an upsert_test database:
@@ -166,3 +174,5 @@ Bug reports and pull requests are welcome on GitHub at https://github.com/jesjos
166
174
  - Andrii Dmytrenko ([@Antti](https://github.com/Antti))
167
175
  - Alexia McDonald ([@alexiamcdonald](https://github.com/alexiamcdonald))
168
176
  - Timo Schilling ([@timoschilling](https://github.com/timoschilling))
177
+ - Benedikt Deicke ([@benedikt](https://github.com/benedikt))
178
+ - Daniel Cooper ([@danielcooper](https://github.com/danielcooper))
data/Rakefile CHANGED
@@ -13,7 +13,7 @@ task :setup_and_run_spec do |rake_task|
13
13
 
14
14
  require File.expand_path('../spec/dummy/config/environment.rb', __FILE__)
15
15
 
16
- if Rails.version >= '5.2.0.rc1'
16
+ if Rails.version >= '5.2.0'
17
17
  ActiveRecord::Base.connection.migrations_paths << 'spec/dummy/db/migrate'
18
18
  end
19
19
 
@@ -31,19 +31,19 @@ module ActiveRecordUpsert
31
31
  end
32
32
 
33
33
  def _upsert_record(upsert_attribute_names = changed, arel_condition = nil)
34
- existing_attributes = arel_attributes_with_values_for_create(self.attributes.keys)
34
+ existing_attributes = attributes_with_values_for_create(self.attributes.keys)
35
35
  values = self.class._upsert_record(existing_attributes, upsert_attribute_names, [arel_condition].compact)
36
36
  @new_record = false
37
37
  values
38
38
  end
39
39
 
40
40
  module ClassMethods
41
- def upsert!(attributes, arel_condition: nil, &block)
41
+ def upsert!(attributes, arel_condition: nil, validate: true, &block)
42
42
  if attributes.is_a?(Array)
43
43
  attributes.collect { |hash| upsert(hash, &block) }
44
44
  else
45
45
  new(attributes, &block).upsert!(
46
- attributes: attributes.keys, arel_condition: arel_condition, validate: true
46
+ attributes: attributes.keys, arel_condition: arel_condition, validate: validate
47
47
  )
48
48
  end
49
49
  end
@@ -57,10 +57,11 @@ module ActiveRecordUpsert
57
57
  def _upsert_record(existing_attributes, upsert_attributes_names, wheres) # :nodoc:
58
58
  upsert_keys = self.upsert_keys || [primary_key]
59
59
  upsert_attributes_names = upsert_attributes_names - [*upsert_keys, 'created_at']
60
- values_for_upsert = existing_attributes.select { |a| upsert_attributes_names.include?(a.name) }
60
+ values_for_upsert = existing_attributes.select { |(name, _value)| upsert_attributes_names.include?(name) }
61
61
 
62
62
  insert_manager = arel_table.compile_upsert(
63
63
  upsert_keys,
64
+ upsert_options,
64
65
  _substitute_values(values_for_upsert),
65
66
  _substitute_values(existing_attributes),
66
67
  wheres
@@ -71,14 +72,20 @@ module ActiveRecordUpsert
71
72
 
72
73
  def upsert_keys(*keys)
73
74
  return @_upsert_keys if keys.empty?
75
+ options = keys.extract_options!
74
76
  keys = keys.first if keys.size == 1 # support single string/symbol, multiple string/symbols, and array
75
77
  return if keys.nil?
76
78
  @_upsert_keys = Array(keys).map(&:to_s)
79
+ @_upsert_options = options
80
+ end
81
+
82
+ def upsert_options
83
+ @_upsert_options || {}
77
84
  end
78
85
 
79
86
  def inherited(subclass)
80
87
  super
81
- subclass.upsert_keys(upsert_keys)
88
+ subclass.upsert_keys(upsert_keys, upsert_options)
82
89
  end
83
90
  end
84
91
  end
@@ -11,10 +11,11 @@
11
11
  # end
12
12
  module Arel
13
13
  module Crud
14
- def compile_upsert(upsert_keys, upsert_values, insert_values, wheres)
14
+ def compile_upsert(upsert_keys, upsert_options, upsert_values, insert_values, wheres)
15
15
  on_conflict_do_update = OnConflictDoUpdateManager.new
16
16
 
17
17
  on_conflict_do_update.target = self[upsert_keys.join(',')]
18
+ on_conflict_do_update.target_condition = upsert_options[:where]
18
19
  on_conflict_do_update.wheres = wheres
19
20
  on_conflict_do_update.set(upsert_values)
20
21
 
@@ -1,12 +1,13 @@
1
1
  module Arel
2
2
  module Nodes
3
3
  class OnConflict < Node
4
- attr_accessor :target, :action
4
+ attr_accessor :target, :where, :action
5
5
 
6
6
  def initialize
7
7
  super
8
8
  @target = nil
9
9
  @action = nil
10
+ @where = nil
10
11
  end
11
12
 
12
13
  def hash
@@ -8,6 +8,10 @@ module Arel
8
8
  @ctx = @ast
9
9
  end
10
10
 
11
+ def target_condition= where
12
+ @ast.where = where
13
+ end
14
+
11
15
  def target= column
12
16
  @ast.target = column
13
17
  end
@@ -14,6 +14,7 @@ module ActiveRecordUpsert
14
14
  def visit_Arel_Nodes_OnConflict o, collector
15
15
  collector << "ON CONFLICT "
16
16
  collector << " (#{quote_column_name o.target.name}) ".gsub(',', '","')
17
+ collector << " WHERE #{o.where}" if o.where
17
18
  maybe_visit o.action, collector
18
19
  end
19
20
 
@@ -22,6 +22,7 @@ module ActiveRecordUpsert
22
22
 
23
23
  on_conflict_do_update = ::Arel::OnConflictDoUpdateManager.new
24
24
  on_conflict_do_update.target = arel_table[upsert_keys.join(',')]
25
+ on_conflict_do_update.target_condition = self.klass.upsert_options[:where]
25
26
  on_conflict_do_update.wheres = wheres
26
27
  on_conflict_do_update.set(vals_for_upsert)
27
28
 
@@ -1,3 +1,3 @@
1
1
  module ActiveRecordUpsert
2
- VERSION = "0.7.4"
2
+ VERSION = "0.8.0"
3
3
  end
@@ -11,8 +11,10 @@ end
11
11
  require 'active_record_upsert/arel'
12
12
  require 'active_record_upsert/active_record'
13
13
 
14
- require 'active_record_upsert/compatibility/rails51.rb' if Rails.version >= '5.1.0' && Rails.version < '5.2.0.rc1'
15
- require 'active_record_upsert/compatibility/rails50.rb' if Rails.version >= '5.0.0' && Rails.version < '5.1.0'
14
+ version = defined?(Rails) ? Rails.version : ActiveRecord.version.to_s
15
+
16
+ require 'active_record_upsert/compatibility/rails51.rb' if version >= '5.1.0' && version < '5.2.0'
17
+ require 'active_record_upsert/compatibility/rails50.rb' if version >= '5.0.0' && version < '5.1.0'
16
18
 
17
19
  module ActiveRecordUpsert
18
20
  # Your code goes here...
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: active_record_upsert
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.4
4
+ version: 0.8.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jesper Josefsson
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: exe
11
11
  cert_chain: []
12
- date: 2018-02-14 00:00:00.000000000 Z
12
+ date: 2018-04-24 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activerecord
@@ -79,6 +79,11 @@ executables: []
79
79
  extensions: []
80
80
  extra_rdoc_files: []
81
81
  files:
82
+ - Gemfile.base
83
+ - Gemfile.rails-5-0
84
+ - Gemfile.rails-5-1
85
+ - Gemfile.rails-5-2
86
+ - Gemfile.rails-master
82
87
  - LICENSE
83
88
  - README.md
84
89
  - Rakefile
@@ -125,7 +130,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
125
130
  version: '0'
126
131
  requirements: []
127
132
  rubyforge_project:
128
- rubygems_version: 2.7.5
133
+ rubygems_version: 2.7.6
129
134
  signing_key:
130
135
  specification_version: 4
131
136
  summary: Real PostgreSQL 9.5+ upserts using ON CONFLICT for ActiveRecord