active_record_upsert 0.7.4 → 0.8.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
  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