Skip to content

Instantly share code, notes, and snippets.

@alexvollmer
Created May 11, 2016 18:18
Show Gist options
  • Save alexvollmer/425db865b08bcd60d131bd38e32598b2 to your computer and use it in GitHub Desktop.
Save alexvollmer/425db865b08bcd60d131bd38e32598b2 to your computer and use it in GitHub Desktop.
#!/usr/bin/env ruby
identifying_attrs = {
updateable_type: 'Contact',
updateable_id: 123,
external_source_id: 123,
attribute_name: 'title'
}
non_identifying_attrs = {
attribute_value: 'Grand PooBah'
}
def to_bind_params(attrs, table)
attrs.to_a.map do |pair|
[table[pair.first], pair.last]
end
end
entity_changes = Arel::Table.new(:entity_changes, ActiveRecord::Base)
insert_manager = Arel::InsertManager.new(ActiveRecord::Base)
insert_manager.insert(to_bind_params(identifying_attrs.merge(non_identifying_attrs), entity_changes))
update_manager = Arel::UpdateManager.new(ActiveRecord::Base)
where_clause = identifying_attrs.to_a.map do |pair|
entity_changes[pair.first.to_s].eq(pair.last)
end
update_manager.table(entity_changes).where(entity_changes.create_and(where_clause))
update_manager.set(to_bind_params(non_identifying_attrs, entity_changes))
sql = insert_manager.to_sql
conflict_keys = identifying_attrs.keys.map { |k| k.to_s }.join(', ')
sql << "\nON CONFLICT (#{conflict_keys}) DO\n"
sql << update_manager.to_sql.sub(/^UPDATE "#{entity_changes.name}"/, "UPDATE")
puts sql
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment