Skip to content

Commit

Permalink
Work in progress: rails 5.1/5.0 compat (#82)
Browse files Browse the repository at this point in the history
* Try to recreate id not being set

* Don't attempt to upsert non-persistent attributes

* Set attributes after upsert

* Attempt to restore support for rails 5.1

* Allow failures for rails master
  • Loading branch information
jesjos authored and olleolleolle committed Sep 18, 2018
1 parent b7c78cf commit da6e6e4
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 3 deletions.
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ addons:
postgresql: '9.5'
matrix:
allow_failures:
- env: RAILS_VERSION=master
- gemfile: Gemfile.rails-master
deploy:
provider: rubygems
api_key:
Expand Down
16 changes: 14 additions & 2 deletions lib/active_record_upsert/compatibility/rails51.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,21 @@ module ActiveRecordUpsert
module ActiveRecord
module PersistenceExtensions
def _upsert_record(upsert_attribute_names = changed, arel_condition = nil)
existing_attributes = arel_attributes_with_values_for_create(self.attributes.keys)
upsert_attribute_names = upsert_attribute_names.map { |name| _prepare_column(name) } & self.class.column_names
existing_attributes = arel_attributes_with_values_for_create(self.class.column_names)
values = self.class.unscoped.upsert(existing_attributes, upsert_attribute_names, [arel_condition].compact)
@new_record = false
@attributes = self.class.attributes_builder.build_from_database(values.first.to_h)
values
end

def _prepare_column(name)
if self.class.reflections.key?(name)
self.class.reflections[name].foreign_key
else
name
end
end
end

module RelationExtensions
Expand All @@ -20,8 +30,10 @@ def upsert(existing_attributes, upsert_attributes, wheres) # :nodoc:
on_conflict_binds = binds.select(&upsert_keys_filter)
vals_for_upsert = substitutes.select { |s| upsert_keys_filter.call(s.first) }

target = arel_table[upsert_options.key?(:literal) ? ::Arel::Nodes::SqlLiteral.new(upsert_options[:literal]) : upsert_keys.join(',')]

on_conflict_do_update = ::Arel::OnConflictDoUpdateManager.new
on_conflict_do_update.target = arel_table[upsert_keys.join(',')]
on_conflict_do_update.target = target
on_conflict_do_update.target_condition = self.klass.upsert_options[:where]
on_conflict_do_update.wheres = wheres
on_conflict_do_update.set(vals_for_upsert)
Expand Down
7 changes: 7 additions & 0 deletions spec/active_record/key_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,13 @@ module ActiveRecord
expect(record.created_at).not_to be_nil
expect(record.updated_at).not_to be_nil
end

it 'sets id' do
record.wheels_count = 1
expect(record.id).to be_nil
record.upsert(attributes: [:wheels_count])
expect(record.id).not_to be_nil
end
end

context 'when the record already exists' do
Expand Down

0 comments on commit da6e6e4

Please sign in to comment.