Skip to content

Commit 09e0411

Browse files
authored
Added update_or_create method (#4)
* Added update_or_create method This new method allows us to use multiple keys to identify records, it replaces the implementation of `.refresh`. Fixes #2 * Fixed readme examples * bump version to 1.0 * Send log messages to $stderr instead of stdout
1 parent b61840c commit 09e0411

File tree

4 files changed

+63
-18
lines changed

4 files changed

+63
-18
lines changed

README.md

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,16 @@ Add this line to your application's deploy.rb file:
3737
The below example ensures that there are 3 users existing in the database after running the 'rake reference_data:load'
3838

3939
### db/reference/000_users.rb
40-
Easy::ReferenceData.refresh User, :system_code, 'nigel', name: 'Nigel Ramsay', email: '[email protected]'
41-
Easy::ReferenceData.refresh User, :system_code, 'fred', name: 'Fred Schmitt', email: '[email protected]'
42-
Easy::ReferenceData.refresh User, :system_code, 'bert', name: 'Bert Symthe', email: '[email protected]'
40+
Easy::ReferenceData.update_or_create User, {system_code: 'nigel', name: 'Nigel Ramsay', email: '[email protected]'}, keys: [:system_code]
41+
Easy::ReferenceData.update_or_create User, {system_code: 'fred', name: 'Fred Schmitt', email: '[email protected]'}, keys: [:system_code]
42+
Easy::ReferenceData.update_or_create User, {system_code: 'bert', name: 'Bert Symthe', email: '[email protected]'}, keys: [:system_code]
43+
44+
Multiple keys can be used to identify records that would otherwise not have a unique attribute
45+
46+
### db/reference/000_prices.rb
47+
Easy::ReferenceData.update_or_create Price, {product_id: 1, type: "Price::RetailPrice", price: 5}, keys: [:product_id, :type]
48+
Easy::ReferenceData.update_or_create Price, {product_id: 1, type: "Price::CostPrice", price: 4}, keys: [:product_id, :type]
49+
Easy::ReferenceData.update_or_create Price, {product_id: 2, type: "Price::RetailPrice", price: 5}, keys: [:product_id, :type]
4350

4451
## Contributing
4552

lib/easy/reference_data/refresh.rb

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,31 @@
1+
require 'active_support'
2+
13
module Easy
24
module ReferenceData
35
def self.refresh(clazz, unique_attribute_symbol, unique_attribute_value, attributes)
4-
record = clazz.where(unique_attribute_symbol => unique_attribute_value).first
6+
self.update_or_create(clazz, attributes.merge(unique_attribute_symbol => unique_attribute_value), keys: [unique_attribute_symbol])
7+
end
58

6-
if record.nil?
7-
record = clazz.new
8-
record.send "#{unique_attribute_symbol}=", unique_attribute_value
9-
end
9+
def self.update_or_create(clazz, attributes, options)
10+
unique_attribute_keys = options.fetch(:keys)
1011

11-
attributes.each_pair do |key, value|
12-
record.send "#{key}=", value
13-
end
12+
record = clazz.where(attributes.slice(*unique_attribute_keys)).first_or_initialize
1413

1514
if record.new_record?
16-
puts "..creating #{clazz}(#{unique_attribute_value})"
17-
elsif record.changed?
18-
puts "..updating #{clazz}(#{unique_attribute_value})"
15+
$stderr.puts "..creating #{clazz}(#{attributes.slice(*unique_attribute_keys)})"
16+
else
17+
$stderr.puts "..updating #{clazz}(#{attributes.slice(*unique_attribute_keys)})"
1918
end
2019

2120
begin
22-
record.save!
21+
record.update_attributes!(attributes)
2322
rescue
24-
puts "Save failed for #{record.class}[#{unique_attribute_symbol}: #{unique_attribute_value}] with attributes #{attributes.inspect}"
23+
$stderr.puts "Save failed for #{record.class} with attributes #{attributes.inspect}"
2524
raise
2625
end
2726

2827
record
2928
end
29+
3030
end
3131
end

lib/easy/reference_data/version.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
module Easy
22
module ReferenceData
3-
VERSION = "0.1.2"
3+
VERSION = "1.0.0"
44
end
5-
end
5+
end

spec/easy/reference_data/refresh_spec.rb

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,44 @@
33

44
RSpec.describe Easy::ReferenceData do
55

6+
describe ".update_or_create" do
7+
context "with a single unique attribute" do
8+
context "and an existing record" do
9+
10+
it "does not change the record" do
11+
user = User.create(system_code: 1)
12+
13+
expect{ Easy::ReferenceData.update_or_create(User, {system_code: 1}, keys: [:system_code])}.not_to change{ User.count }
14+
end
15+
16+
context "with additional attribues" do
17+
it "updates the existing record" do
18+
user = User.create(system_code: 1, name: "Jo")
19+
20+
expect{ Easy::ReferenceData.update_or_create(User, {system_code: 1, name: "Jane"}, keys: [:system_code])}.to change{ user.reload.name }.to "Jane"
21+
end
22+
end
23+
end
24+
25+
context "and no existing record" do
26+
it "creates a new record" do
27+
expect{ Easy::ReferenceData.update_or_create(User, {system_code: 1}, keys: [:system_code])}.to change{ User.count }
28+
end
29+
end
30+
31+
end
32+
33+
context "with multiple attributes" do
34+
it "updates the matching record" do
35+
jo_smith = User.create(system_code: 1, name: "Jo", email: "[email protected]")
36+
jo_brown = User.create(system_code: 1, name: "Jo", email: "[email protected]")
37+
38+
expect{ Easy::ReferenceData.update_or_create(User, {name: "Jo", email: "[email protected]", system_code: 2}, keys: [:name, :email])}.to change{ jo_brown.reload.system_code }.to 2
39+
end
40+
41+
end
42+
end
43+
644
describe ".refresh" do
745

846
context "with a unique attribue" do

0 commit comments

Comments
 (0)