standard_procedure_fabrik 0.1.0 → 0.1.1

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: 473c93f4575e1ac907de0db91f5e306c9f38b2bd8d8c67c0147d0ffffb1ac6cc
4
- data.tar.gz: 7aea538f381c7cb6d7898c460d6c989d959fe4e1220ea3043a15f15f60d6db35
3
+ metadata.gz: fc634b02a078fda169f5f93bc1bd4c607b1245d3d5d866a9224ced85fb3576a1
4
+ data.tar.gz: e57ba5a0e6cc50cd061fee1608e2fb096e7fab885e6389a3fd819c63530880bd
5
5
  SHA512:
6
- metadata.gz: 6a78111d8b8b26e318399cceb97b6e701db06286c65f70977be7766bbc6ad099e9fa934b9f3e779b05c78dbdf92021450fd1144d9cad4f2106c7e3ebac87745f
7
- data.tar.gz: c1f2c5996540d5bc694732d848fbf7922f4c8698b2f1d33d0a0f430dee16c94bf965e5387ba42681150339e5d7047d55a461216eb5b3ee9e5962cd3b61d8529d
6
+ metadata.gz: 51e2f129f76aa9a3f08b8cd53b54891d8a5d6fdefb41baa03462c8227bea30a0c9497c716a620805e242dfcfff4f54e9b95e180cb4811b9e2915c5ca3a07ef44
7
+ data.tar.gz: 964e3ceab133674e4366d98b36243d5d9c9e5b0642253a4a7c43e3300150560aa8c8f218ed87eec902c9136f3ca1e169e01c451dbab9f3cc9a5e82891457a581
data/CHANGELOG.md CHANGED
@@ -1,3 +1,7 @@
1
+ ## [0.1.1] - 2024-12-29
2
+
3
+ - Pass the database through to defaults (so you can create dependent models)
4
+
1
5
  ## [0.1.0] - 2024-12-19
2
6
 
3
7
  - Initial release
data/README.md CHANGED
@@ -1,66 +1,66 @@
1
1
  # Fabrik
2
2
 
3
- ## Simplify your database seeds and test fixtures.
3
+ ## Simplify your database seeds and test fixtures.
4
4
 
5
- Fabrik is a factory for your ActiveRecord models.
5
+ Fabrik is a factory for your ActiveRecord models.
6
6
 
7
- It's designed to be used in both your test cases and in your database seeds.
7
+ It's designed to be used in both your test cases and in your database seeds.
8
+
9
+ And I think the API is pretty nice and the code is pretty simple.
8
10
 
9
- And I think the API is pretty nice and the code is pretty simple.
10
-
11
11
  ## Database seeds
12
12
 
13
- Database seeds are great.
13
+ Database seeds are great.
14
14
 
15
- Screwed up your development database? Just drop it, rebuild it and load in your starting data.
15
+ Screwed up your development database? Just drop it, rebuild it and load in your starting data.
16
16
 
17
- Added a new feature and want to show people what it looks like? Add some new records into your seeds, run them, then you've got a nice set of demo data, all pre-loaded.
17
+ Added a new feature and want to show people what it looks like? Add some new records into your seeds, run them, then you've got a nice set of demo data, all pre-loaded.
18
18
 
19
- For this to work, seeds need to be idempotent. When you run your seeds against a database with existing data, it should only insert the new stuff, leaving the old untouched.
19
+ For this to work, seeds need to be idempotent. When you run your seeds against a database with existing data, it should only insert the new stuff, leaving the old untouched.
20
20
 
21
- Fabrik does this.
21
+ Fabrik does this.
22
22
 
23
23
  ## Specs and tests
24
24
 
25
- I love RSpec. Other test frameworks (cough; minitest) are available.
25
+ I love RSpec. Other test frameworks (cough; minitest) are available.
26
26
 
27
- And if you're writing Rails apps, your tests or specs are, most likely, going to be using ActiveRecord models which end up hitting the database. That's just how Rails works, no matter what the isolationists say.
27
+ And if you're writing Rails apps, your tests or specs are, most likely, going to be using ActiveRecord models which end up hitting the database. That's just how Rails works, no matter what the isolationists say.
28
28
 
29
- So, when setting up your test fixtures, you want to set up the smallest amount of data to prove your case.
29
+ So, when setting up your test fixtures, you want to set up the smallest amount of data to prove your case.
30
30
 
31
- And, because tests are documentation, you want that setup to be there, next to the test code, so anyone reading it can understand how everything hangs together.
31
+ And, because tests are documentation, you want that setup to be there, next to the test code, so anyone reading it can understand how everything hangs together.
32
32
 
33
- Fabrik does this.
33
+ Fabrik does this.
34
34
 
35
35
  ## Configuration
36
36
 
37
- Fabrik allows you to configure three aspects of how you create your objects.
37
+ Fabrik allows you to configure three aspects of how you create your objects.
38
38
 
39
39
  ### Default attributes
40
40
 
41
- When you're writing a spec, you probably only care about one aspect of the model involved.
41
+ When you're writing a spec, you probably only care about one aspect of the model involved.
42
42
 
43
- So Fabrik allows you to set default attributes; then when you're creating a model, you can specify the ones you're interested in and ignore all the rest.
43
+ So Fabrik allows you to set default attributes; then when you're creating a model, you can specify the ones you're interested in and ignore all the rest.
44
44
 
45
45
  ```ruby
46
46
  db.configure do
47
47
  with Person do
48
- defaults first_name: -> { "Alice" }, last_name: -> { Faker::Name.last_name }, age: -> { 33 }
48
+ defaults first_name: ->(db) { "Alice" }, last_name: ->(db) { Faker::Name.last_name }, age: ->(db) { 33 }
49
49
  end
50
50
  end
51
51
 
52
52
  @alice = db.people.create last_name: "Anteater"
53
53
 
54
- puts @alice.first_name # => Alice
55
- puts @alice.last_name # => Anteater
54
+ puts @alice.first_name # => Alice
55
+ puts @alice.last_name # => Anteater
56
56
  puts @alice.age # => 33
57
57
  ```
58
58
 
59
59
  ### Uniqueness
60
60
 
61
- When you've got a database packed with existing data, you don't want your seeds to fail because of a uniqueness constraint. Or your tests to fail because suddenly they're finding two records when they were only expecting one.
61
+ When you've got a database packed with existing data, you don't want your seeds to fail because of a uniqueness constraint. Or your tests to fail because suddenly they're finding two records when they were only expecting one.
62
62
 
63
- So Fabrik lets you define what makes a model unique. Then when you create it, it checks for an existing record first and only creates a new one if the original is not found.
63
+ So Fabrik lets you define what makes a model unique. Then when you create it, it checks for an existing record first and only creates a new one if the original is not found.
64
64
 
65
65
  ```ruby
66
66
  db.configure do
@@ -71,25 +71,25 @@ end
71
71
  @alice = db.people.create first_name: "Alice", last_name: "Aardvark", email: "alice@example.com"
72
72
  @zac = db.people.create first_name: "Zac", last_name: "Zebra", email: "alice@example.com"
73
73
 
74
- @alice == @zac # => true
74
+ @alice == @zac # => true
75
75
  puts @zac.first_name # => Alice
76
76
  ```
77
77
 
78
78
  ### Special processing
79
79
 
80
- Some models are special. They can't live on their own. Their invariants won't let them. Maybe a `Company` cannot exist without a `CEO`. While your main application logic can ensure that's always the case, when you're writing your tests, it becomes a pain specifying it over and over again.
80
+ Some models are special. They can't live on their own. Their invariants won't let them. Maybe a `Company` cannot exist without a `CEO`. While your main application logic can ensure that's always the case, when you're writing your tests, it becomes a pain specifying it over and over again.
81
81
 
82
- So Fabrik lets you define specific processing that happens after a new record is created.
82
+ So Fabrik lets you define specific processing that happens after a new record is created.
83
83
 
84
84
  ```ruby
85
85
  db.configure do
86
- with Company do
86
+ with Company do
87
87
  defaults name: -> { Faker::Company.name }
88
88
  after_create do |company, db|
89
89
  db.employees.create company: company, role: "CEO"
90
90
  end
91
- end
92
- with Employee do
91
+ end
92
+ with Employee do
93
93
  defaults first_name: -> { Faker::Name.first_name }, last_name: -> { Faker::Name.last_name }, role: -> { "Cleaner" }
94
94
  end
95
95
  end
@@ -99,9 +99,9 @@ puts Company.find_by(name: "MegaCorp").employees.size # => 1
99
99
 
100
100
  ## References
101
101
 
102
- You've created a load of models. And you need to reference them to create more models. You could search for them by hand, but that's for chumps.
102
+ You've created a load of models. And you need to reference them to create more models. You could search for them by hand, but that's for chumps.
103
103
 
104
- So Fabrik let's you give your models a label. And then refer back to that model using the label.
104
+ So Fabrik let's you give your models a label. And then refer back to that model using the label.
105
105
 
106
106
  ```ruby
107
107
  db.people.create :alice, first_name: "Alice"
@@ -113,7 +113,7 @@ puts db.people[:alice] # => Alice
113
113
 
114
114
  You've got a load of models in your application. Fabrik allows you to configure some rules for each one. But not all of them need special processing. Why waste your time telling Fabrik about all these classes when you've got more important things to do?
115
115
 
116
- So Fabrik takes a guess at any names you give it and tries its best to figure out which class you mean.
116
+ So Fabrik takes a guess at any names you give it and tries its best to figure out which class you mean.
117
117
 
118
118
  ```ruby
119
119
  class Intergalactic::Spaceship < ApplicationRecord
@@ -125,18 +125,18 @@ db.intergalactic_spaceships.create :ufo
125
125
  puts Intergalactic::Spaceship.count # => 1
126
126
  ```
127
127
 
128
- Or maybe you're writing a Rails engine and all your classes are namespaced. Typing long names is so _boring_.
128
+ Or maybe you're writing a Rails engine and all your classes are namespaced. Typing long names is so _boring_.
129
129
 
130
- So Fabrik lets you register an alternative name for your classes.
130
+ So Fabrik lets you register an alternative name for your classes.
131
131
 
132
132
  ```ruby
133
- db.configure do
134
- with MyAccountsPackageEngine::Invoice, as: :invoice do
135
- defaults due_date: -> { 7.days.from_now }
133
+ db.configure do
134
+ with MyAccountsPackageEngine::Invoice, as: :invoice do
135
+ defaults due_date: ->(db) { 7.days.from_now }
136
136
  end
137
- end
137
+ end
138
138
 
139
- db.invoices.create :overdue_invoice, due_date: 1.day.ago
139
+ db.invoices.create :overdue_invoice, due_date: 1.day.ago
140
140
  ```
141
141
 
142
142
  ## Installation
@@ -147,59 +147,59 @@ Add `standard_procedure_fabrik` to your `Gemfile`
147
147
  bundle add standard_procedure_fabrik
148
148
  ```
149
149
 
150
- If you're only using it for tests, add it to your `test` group. If you're using it for seeds, add it with all your other gems. While you're at it, add [Faker](https://github.com/faker-ruby/faker) as well - at the very least, it will probably make you smile with some of the stuff it generates for your test data.
150
+ If you're only using it for tests, add it to your `test` group. If you're using it for seeds, add it with all your other gems. While you're at it, add [Faker](https://github.com/faker-ruby/faker) as well - at the very least, it will probably make you smile with some of the stuff it generates for your test data.
151
151
 
152
152
  ## Usage
153
153
 
154
154
  ### Localised (for tests)
155
155
 
156
- Create an instance of a [Fabrik::Database](/lib/fabrik/database.rb), configure it and use it.
156
+ Create an instance of a [Fabrik::Database](/lib/fabrik/database.rb), configure it and use it.
157
157
 
158
158
  ```ruby
159
- db = Fabrik::Database.new
160
- db.configure do
161
- with Person do
162
- defaults first_name: -> { Faker::Name.first_name }, last_name: -> { Faker::Name.last_name }, email: -> { Faker::Internet.email }
159
+ db = Fabrik::Database.new
160
+ db.configure do
161
+ with Person do
162
+ defaults first_name: ->(db) { Faker::Name.first_name }, last_name: ->(db) { Faker::Name.last_name }, email: ->(db) { Faker::Internet.email }
163
163
  end
164
164
  end
165
165
 
166
166
  db.people.create :alice, first_name: "Alice"
167
167
  ```
168
168
 
169
- In an RSpec:
169
+ In an RSpec:
170
170
 
171
171
  ```ruby
172
- RSpec.describe "Whatever" do
172
+ RSpec.describe "Whatever" do
173
173
  let(:db) { Fabrik::Database.new }
174
- before do
175
- db.configure do
174
+ before do
175
+ db.configure do
176
176
  # ... whatever
177
177
  end
178
178
  end
179
179
  end
180
180
  ```
181
181
 
182
- In a minitest ... I don't know, I've not used minitest in years but I'm sure it's easy enough.
182
+ In a minitest ... I don't know, I've not used minitest in years but I'm sure it's easy enough.
183
183
 
184
184
  ### Global (for seeds and generally creating stuff)
185
185
 
186
- Configure the global `Fabrik::Database`, then use it.
186
+ Configure the global `Fabrik::Database`, then use it.
187
187
 
188
188
  ```ruby
189
- Fabrik.configure do
190
- with Person do
191
- defaults first_name: -> { Faker::Name.first_name }, last_name: -> { Faker::Name.last_name }, email: -> { Faker::Internet.email }
189
+ Fabrik.configure do
190
+ with Person do
191
+ defaults first_name: ->(db) { Faker::Name.first_name }, last_name: ->(db) { Faker::Name.last_name }, email: ->(db) { Faker::Internet.email }
192
192
  end
193
193
  end
194
194
 
195
195
  Fabrik.db.people.create :alice, first_name: "Alice"
196
196
  ```
197
197
 
198
- Watch out - because this uses a global instance, it's not thread-safe. That's not an issue if you're just using it for database seeds or in most test runners(single-threaded or parallelised with multiple processes). But it *might* cause problems if you're using threads to parallelise your tests, or you're reconfiguring while your application is running.
198
+ Watch out - because this uses a global instance, it's not thread-safe. That's not an issue if you're just using it for database seeds or in most test runners(single-threaded or parallelised with multiple processes). But it *might* cause problems if you're using threads to parallelise your tests, or you're reconfiguring while your application is running.
199
199
 
200
200
  ## Development
201
201
 
202
- Important note: this gem is not under the MIT Licence - it's under the [LGPL](/LICENSE). This may or may not make it suitable for your use. I have reasons for this, which don't belong in a README. But the net result is, this library is open-source, it's free software and you can license *your own* code any way you want. But if you change *this code*, you have to publish those changes under the same rules.
202
+ Important note: this gem is not under the MIT Licence - it's under the [LGPL](/LICENSE). This may or may not make it suitable for your use. I have reasons for this, which don't belong in a README. But the net result is, this library is open-source, it's free software and you can license *your own* code any way you want. But if you change *this code*, you have to publish those changes under the same rules.
203
203
 
204
204
  So, fork the repo, bundle install, add RSpecs for the changes you want to make and `rake spec` to run the tests. Then send me a pull request. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
205
205
 
@@ -212,8 +212,8 @@ Bug reports and pull requests are welcome on GitHub at https://github.com/standa
212
212
 
213
213
  ### Code of Conduct
214
214
 
215
- Don't be a dick.
215
+ Don't be a dick.
216
216
 
217
- If you think you're being reasonable but most people think you're being a dick, then you're not being reasonable, you're actually being a dick.
217
+ If you think you're being reasonable but most people think you're being a dick, then you're not being reasonable, you're actually being a dick.
218
218
 
219
- We're not computers - we're human beings. And human beings are soft, squishy and emotional. That's just how it is.
219
+ We're not computers - we're human beings. And human beings are soft, squishy and emotional. That's just how it is.
@@ -0,0 +1 @@
1
+ 7946813b20b9d8a66c9fa421ead1466b55cd64170be817bd9f49c23aa69e9c9390a5d3b161640b0a5058669a0435c8431ca33a448c43ac42ae2f1c6cbaffc4e3
@@ -91,7 +91,9 @@ module Fabrik
91
91
 
92
92
  private def default_attributes = @blueprint.default_attributes
93
93
 
94
- private def find_or_create_record(attributes) = klass.find_by(**attributes.slice(*search_keys)) || create_record(attributes)
94
+ private def find_or_create_record(attributes) = find_record(attributes) || create_record(attributes)
95
+
96
+ private def find_record(attributes) = attributes.slice(*search_keys).empty? ? nil : klass.find_by(**attributes.slice(*search_keys))
95
97
 
96
98
  private def create_record(attributes)
97
99
  klass.create(**attributes_with_defaults(attributes)).tap do |record|
@@ -101,7 +103,7 @@ module Fabrik
101
103
 
102
104
  private def attributes_with_defaults attributes
103
105
  attributes_to_generate = default_attributes.keys - attributes.keys
104
- attributes_to_generate.each_with_object({}) { |name, generated_attributes| generated_attributes[name] = default_attributes[name].call }.merge(attributes)
106
+ attributes_to_generate.each_with_object({}) { |name, generated_attributes| generated_attributes[name] = default_attributes[name].call(@db) }.merge(attributes)
105
107
  end
106
108
  end
107
109
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Fabrik
4
- VERSION = "0.1.0"
4
+ VERSION = "0.1.1"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: standard_procedure_fabrik
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Rahoul Baruah
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-12-20 00:00:00.000000000 Z
11
+ date: 2024-12-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -52,6 +52,7 @@ files:
52
52
  - README.md
53
53
  - Rakefile
54
54
  - checksums/standard_procedure_fabrik-0.1.0.gem.sha512
55
+ - checksums/standard_procedure_fabrik-0.1.1.gem.sha512
55
56
  - lib/fabrik.rb
56
57
  - lib/fabrik/database.rb
57
58
  - lib/fabrik/version.rb