propel_api 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/CHANGELOG.md +59 -0
- data/LICENSE +21 -0
- data/README.md +320 -0
- data/Rakefile +36 -0
- data/lib/generators/propel_api/USAGE +8 -0
- data/lib/generators/propel_api/controller/controller_generator.rb +208 -0
- data/lib/generators/propel_api/core/base.rb +19 -0
- data/lib/generators/propel_api/core/configuration_methods.rb +187 -0
- data/lib/generators/propel_api/core/named_base.rb +457 -0
- data/lib/generators/propel_api/core/path_generation_methods.rb +45 -0
- data/lib/generators/propel_api/core/relationship_inferrer.rb +117 -0
- data/lib/generators/propel_api/install/install_generator.rb +343 -0
- data/lib/generators/propel_api/resource/resource_generator.rb +433 -0
- data/lib/generators/propel_api/templates/config/propel_api.rb.tt +149 -0
- data/lib/generators/propel_api/templates/controllers/api_controller_graphiti.rb +79 -0
- data/lib/generators/propel_api/templates/controllers/api_controller_propel_facets.rb +76 -0
- data/lib/generators/propel_api/templates/controllers/example_controller.rb.tt +96 -0
- data/lib/generators/propel_api/templates/scaffold/facet_controller_template.rb.tt +80 -0
- data/lib/generators/propel_api/templates/scaffold/facet_model_template.rb.tt +141 -0
- data/lib/generators/propel_api/templates/scaffold/graphiti_controller_template.rb.tt +82 -0
- data/lib/generators/propel_api/templates/scaffold/graphiti_model_template.rb.tt +32 -0
- data/lib/generators/propel_api/templates/seeds/seeds_template.rb.tt +493 -0
- data/lib/generators/propel_api/templates/tests/controller_test_template.rb.tt +485 -0
- data/lib/generators/propel_api/templates/tests/fixtures_template.yml.tt +250 -0
- data/lib/generators/propel_api/templates/tests/integration_test_template.rb.tt +487 -0
- data/lib/generators/propel_api/templates/tests/model_test_template.rb.tt +252 -0
- data/lib/generators/propel_api/unpack/unpack_generator.rb +304 -0
- data/lib/propel_api.rb +3 -0
- metadata +95 -0
@@ -0,0 +1,493 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Seeds for <%= class_name %> model
|
4
|
+
# This file generates realistic test data for development and testing
|
5
|
+
# First loads fixture data (same as tests use), then adds rich Faker data
|
6
|
+
|
7
|
+
require 'faker'
|
8
|
+
|
9
|
+
puts "๐ฑ Seeding <%= table_name %>..."
|
10
|
+
|
11
|
+
# Load fixture data first to ensure tests and development have the same baseline
|
12
|
+
puts "๐ Loading fixture data for consistent test/dev experience..."
|
13
|
+
|
14
|
+
# Only load fixtures if not already in development environment with existing data
|
15
|
+
fixture_count = 0
|
16
|
+
<% unless options[:skip_tenancy] -%>
|
17
|
+
if Rails.env.development? && (Organization.count > 0 || User.count > 0)
|
18
|
+
<% else -%>
|
19
|
+
<% if attributes.any? { |attr| attr.type == :references && attr.name.to_s.match?(/user/) } -%>
|
20
|
+
if Rails.env.development? && User.count > 0
|
21
|
+
<% else -%>
|
22
|
+
if Rails.env.development? && <%= class_name %>.count > 0
|
23
|
+
<% end -%>
|
24
|
+
<% end -%>
|
25
|
+
puts "โน๏ธ Development environment already has data, skipping fixture loading"
|
26
|
+
puts "๐ก Fixtures are automatically loaded during tests - they'll be available there"
|
27
|
+
puts "๐ก To use fixture data in development: rails db:reset && rails db:seed"
|
28
|
+
else
|
29
|
+
# Load fixtures in clean environment
|
30
|
+
puts "๐ฅ Loading fixtures for clean test/dev baseline..."
|
31
|
+
begin
|
32
|
+
# Load all necessary fixtures together to handle dependencies
|
33
|
+
fixture_files = ['<%= table_name %>']
|
34
|
+
<% unless options[:skip_tenancy] -%>
|
35
|
+
fixture_files << 'organizations'
|
36
|
+
fixture_files << 'agencies'
|
37
|
+
<% end -%>
|
38
|
+
<% if attributes.any? { |attr| attr.type == :references && attr.name.to_s.match?(/user/) } -%>
|
39
|
+
fixture_files << 'users'
|
40
|
+
<% end -%>
|
41
|
+
|
42
|
+
ActiveRecord::FixtureSet.create_fixtures(
|
43
|
+
Rails.root.join('test/fixtures'),
|
44
|
+
fixture_files
|
45
|
+
)
|
46
|
+
fixture_count = <%= class_name %>.count
|
47
|
+
puts "โ
Loaded #{fixture_count} fixture <%= table_name %> (same as test data)"
|
48
|
+
rescue => e
|
49
|
+
puts "โ ๏ธ Could not load fixtures: #{e.message}"
|
50
|
+
puts "๐ก This is normal if database already has data or constraints conflict"
|
51
|
+
fixture_count = 0
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
# Clear existing <%= table_name %> generated by this script to avoid duplicates
|
56
|
+
puts "๐งน Clearing any existing generated <%= table_name %>..."
|
57
|
+
# Only destroy <%= table_name %> that were created by Faker (preserve fixtures)
|
58
|
+
if fixture_count > 0
|
59
|
+
# Keep fixture data, only remove Faker-generated records
|
60
|
+
<%= class_name %>.where.not(id: <%= class_name %>.limit(fixture_count).pluck(:id)).destroy_all
|
61
|
+
else
|
62
|
+
# No fixtures loaded, safe to clear all
|
63
|
+
<%= class_name %>.destroy_all
|
64
|
+
end
|
65
|
+
|
66
|
+
# Now add rich, realistic Faker data for development experience
|
67
|
+
puts "๐จ Generating additional realistic <%= table_name %> with Faker..."
|
68
|
+
|
69
|
+
# Use existing organizations, agencies, and users (from fixtures + any additional ones)
|
70
|
+
<% unless options[:skip_tenancy] -%>
|
71
|
+
organizations = Organization.all
|
72
|
+
agencies = Agency.all
|
73
|
+
|
74
|
+
# If we still don't have enough orgs, create some with Faker
|
75
|
+
if organizations.count < 3
|
76
|
+
puts "โ Creating additional organizations..."
|
77
|
+
(3 - organizations.count).times do
|
78
|
+
Organization.create!(name: Faker::Company.name)
|
79
|
+
end
|
80
|
+
organizations = Organization.all
|
81
|
+
end
|
82
|
+
|
83
|
+
# If we still don't have enough agencies, create some with Faker
|
84
|
+
if agencies.count < 5
|
85
|
+
puts "โ Creating additional agencies..."
|
86
|
+
organizations.each do |org|
|
87
|
+
next if agencies.where(organization: org).count >= 2
|
88
|
+
|
89
|
+
(2 - agencies.where(organization: org).count).times do
|
90
|
+
Agency.create!(
|
91
|
+
name: Faker::Company.name + " #{['Department', 'Division', 'Unit', 'Team'].sample}",
|
92
|
+
organization: org
|
93
|
+
)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
agencies = Agency.all
|
97
|
+
end
|
98
|
+
<% end -%>
|
99
|
+
|
100
|
+
<% if attributes.any? { |attr| attr.type == :references && attr.name.to_s.match?(/user/) } -%>
|
101
|
+
users = User.all
|
102
|
+
|
103
|
+
if users.count < 6
|
104
|
+
puts "โ Creating additional users..."
|
105
|
+
<% unless options[:skip_tenancy] -%>
|
106
|
+
organizations.each do |org|
|
107
|
+
next if users.where(organization: org).count >= 2
|
108
|
+
|
109
|
+
(2 - users.where(organization: org).count).times do
|
110
|
+
User.create!(
|
111
|
+
email_address: Faker::Internet.unique.email,
|
112
|
+
username: Faker::Internet.unique.username,
|
113
|
+
first_name: Faker::Name.first_name,
|
114
|
+
last_name: Faker::Name.last_name,
|
115
|
+
password: "password123",
|
116
|
+
organization: org
|
117
|
+
)
|
118
|
+
end
|
119
|
+
end
|
120
|
+
<% else -%>
|
121
|
+
6.times do
|
122
|
+
User.create!(
|
123
|
+
email_address: Faker::Internet.unique.email,
|
124
|
+
username: Faker::Internet.unique.username,
|
125
|
+
first_name: Faker::Name.first_name,
|
126
|
+
last_name: Faker::Name.last_name,
|
127
|
+
password: "password123"
|
128
|
+
)
|
129
|
+
end
|
130
|
+
<% end -%>
|
131
|
+
users = User.all
|
132
|
+
end
|
133
|
+
<% end -%>
|
134
|
+
|
135
|
+
<%= table_name %>_data = []
|
136
|
+
|
137
|
+
# Generate varied, realistic data based on the model attributes
|
138
|
+
30.times do |i|
|
139
|
+
<% unless options[:skip_tenancy] -%>
|
140
|
+
organization = organizations.sample
|
141
|
+
agency = agencies.where(organization: organization).sample || agencies.sample
|
142
|
+
<% end -%>
|
143
|
+
<% if attributes.any? { |attr| attr.type == :references && attr.name.to_s.match?(/user/) } -%>
|
144
|
+
<% unless options[:skip_tenancy] -%>
|
145
|
+
user = users.where(organization: organization).sample || users.sample
|
146
|
+
<% else -%>
|
147
|
+
user = users.sample
|
148
|
+
<% end -%>
|
149
|
+
<% end -%>
|
150
|
+
|
151
|
+
<%= singular_table_name %>_attributes = {}
|
152
|
+
|
153
|
+
<% unless options[:skip_tenancy] -%>
|
154
|
+
# Multi-tenancy: Always assign organization (required) and agency (optional)
|
155
|
+
<%= singular_table_name %>_attributes[:organization] = organization
|
156
|
+
<%= singular_table_name %>_attributes[:agency] = [agency, nil].sample # 50% chance of having agency
|
157
|
+
|
158
|
+
<% end -%>
|
159
|
+
# Assign additional reference attributes dynamically
|
160
|
+
<% attributes.select { |attr| attr.type == :references }.each do |reference| -%>
|
161
|
+
<% # Skip organization and agency if tenancy is included (they're already assigned above) -%>
|
162
|
+
<% unless !options[:skip_tenancy] && (reference.name == 'organization' || reference.name == 'agency') -%>
|
163
|
+
<% if reference.name.to_s.match?(/user/) -%>
|
164
|
+
<%= singular_table_name %>_attributes[:<%= reference.name %>] = user
|
165
|
+
<% else -%>
|
166
|
+
# Handle other reference types - you may need to customize this
|
167
|
+
# <%= singular_table_name %>_attributes[:<%= reference.name %>] = # TODO: Assign appropriate value
|
168
|
+
<% end -%>
|
169
|
+
<% end -%>
|
170
|
+
<% end -%>
|
171
|
+
|
172
|
+
# Generate realistic data for each attribute
|
173
|
+
<% attributes.reject { |attr| attr.type == :references }.each do |attribute| -%>
|
174
|
+
<% if attribute.type == :string -%>
|
175
|
+
<% if attribute.name.to_s.match?(/\A(name|title|label)\z/i) -%>
|
176
|
+
<%= singular_table_name %>_attributes[:<%= attribute.name %>] = Faker::Lorem.words(number: rand(2..4)).map(&:capitalize).join(' ')
|
177
|
+
<% elsif attribute.name.to_s.match?(/\A(email|email_address)\z/i) -%>
|
178
|
+
<%= singular_table_name %>_attributes[:<%= attribute.name %>] = Faker::Internet.unique.email
|
179
|
+
<% elsif attribute.name.to_s.match?(/\A(username)\z/i) -%>
|
180
|
+
<%= singular_table_name %>_attributes[:<%= attribute.name %>] = Faker::Internet.unique.username
|
181
|
+
<% elsif attribute.name.to_s.match?(/\A(phone|phone_number)\z/i) -%>
|
182
|
+
<%= singular_table_name %>_attributes[:<%= attribute.name %>] = Faker::PhoneNumber.phone_number
|
183
|
+
<% elsif attribute.name.to_s.match?(/\A(url|website|web_address)\z/i) -%>
|
184
|
+
<%= singular_table_name %>_attributes[:<%= attribute.name %>] = Faker::Internet.url
|
185
|
+
<% elsif attribute.name.to_s.match?(/\A(slug)\z/i) -%>
|
186
|
+
<%= singular_table_name %>_attributes[:<%= attribute.name %>] = Faker::Internet.slug
|
187
|
+
<% elsif attribute.name.to_s.match?(/\A(status|state)\z/i) -%>
|
188
|
+
<%= singular_table_name %>_attributes[:<%= attribute.name %>] = ['active', 'inactive', 'pending', 'archived', 'draft'].sample
|
189
|
+
<% elsif attribute.name.to_s.match?(/\A(priority)\z/i) -%>
|
190
|
+
<%= singular_table_name %>_attributes[:<%= attribute.name %>] = ['low', 'medium', 'high', 'urgent'].sample
|
191
|
+
<% elsif attribute.name.to_s.match?(/\A(category|type)\z/i) -%>
|
192
|
+
<%= singular_table_name %>_attributes[:<%= attribute.name %>] = Faker::Lorem.word.capitalize
|
193
|
+
<% elsif attribute.name.to_s.match?(/\A(code|sku|identifier)\z/i) -%>
|
194
|
+
<%= singular_table_name %>_attributes[:<%= attribute.name %>] = Faker::Alphanumeric.alphanumeric(number: 8).upcase
|
195
|
+
<% elsif attribute.name.to_s.match?(/\A(color|colour)\z/i) -%>
|
196
|
+
<%= singular_table_name %>_attributes[:<%= attribute.name %>] = Faker::Color.color_name
|
197
|
+
<% elsif attribute.name.to_s.match?(/\A(address)\z/i) -%>
|
198
|
+
<%= singular_table_name %>_attributes[:<%= attribute.name %>] = Faker::Address.street_address
|
199
|
+
<% elsif attribute.name.to_s.match?(/\A(city)\z/i) -%>
|
200
|
+
<%= singular_table_name %>_attributes[:<%= attribute.name %>] = Faker::Address.city
|
201
|
+
<% elsif attribute.name.to_s.match?(/\A(country)\z/i) -%>
|
202
|
+
<%= singular_table_name %>_attributes[:<%= attribute.name %>] = Faker::Address.country
|
203
|
+
<% elsif attribute.name.to_s.match?(/\A(currency)\z/i) -%>
|
204
|
+
<%= singular_table_name %>_attributes[:<%= attribute.name %>] = Faker::Currency.code
|
205
|
+
<% else -%>
|
206
|
+
<%= singular_table_name %>_attributes[:<%= attribute.name %>] = Faker::Lorem.words(number: rand(1..3)).join(' ').titleize
|
207
|
+
<% end -%>
|
208
|
+
<% elsif attribute.type == :text -%>
|
209
|
+
<% if attribute.name.to_s.match?(/\A(description|summary|notes)\z/i) -%>
|
210
|
+
<%= singular_table_name %>_attributes[:<%= attribute.name %>] = Faker::Lorem.paragraphs(number: rand(1..3)).join("\n\n")
|
211
|
+
<% elsif attribute.name.to_s.match?(/\A(content|body)\z/i) -%>
|
212
|
+
<%= singular_table_name %>_attributes[:<%= attribute.name %>] = Faker::Lorem.paragraphs(number: rand(3..6)).join("\n\n")
|
213
|
+
<% elsif attribute.name.to_s.match?(/\A(bio|about)\z/i) -%>
|
214
|
+
<%= singular_table_name %>_attributes[:<%= attribute.name %>] = Faker::Lorem.paragraph(sentence_count: rand(3..8))
|
215
|
+
<% elsif attribute.name.to_s.match?(/\A(comment|review)\z/i) -%>
|
216
|
+
<%= singular_table_name %>_attributes[:<%= attribute.name %>] = Faker::Lorem.paragraph(sentence_count: rand(2..4))
|
217
|
+
<% else -%>
|
218
|
+
<%= singular_table_name %>_attributes[:<%= attribute.name %>] = Faker::Lorem.paragraphs(number: rand(2..4)).join("\n\n")
|
219
|
+
<% end -%>
|
220
|
+
<% elsif attribute.type == :integer -%>
|
221
|
+
<% if attribute.name.to_s.match?(/\A(age)\z/i) -%>
|
222
|
+
<%= singular_table_name %>_attributes[:<%= attribute.name %>] = rand(18..80)
|
223
|
+
<% elsif attribute.name.to_s.match?(/\A(count|quantity|amount|number)\z/i) -%>
|
224
|
+
<%= singular_table_name %>_attributes[:<%= attribute.name %>] = rand(1..100)
|
225
|
+
<% elsif attribute.name.to_s.match?(/\A(priority|order|position|rank)\z/i) -%>
|
226
|
+
<%= singular_table_name %>_attributes[:<%= attribute.name %>] = rand(1..10)
|
227
|
+
<% elsif attribute.name.to_s.match?(/\A(year)\z/i) -%>
|
228
|
+
<%= singular_table_name %>_attributes[:<%= attribute.name %>] = rand(2020..2025)
|
229
|
+
<% elsif attribute.name.to_s.match?(/\A(month)\z/i) -%>
|
230
|
+
<%= singular_table_name %>_attributes[:<%= attribute.name %>] = rand(1..12)
|
231
|
+
<% elsif attribute.name.to_s.match?(/\A(day)\z/i) -%>
|
232
|
+
<%= singular_table_name %>_attributes[:<%= attribute.name %>] = rand(1..28)
|
233
|
+
<% elsif attribute.name.to_s.match?(/\A(rating|score)\z/i) -%>
|
234
|
+
<%= singular_table_name %>_attributes[:<%= attribute.name %>] = rand(1..5)
|
235
|
+
<% elsif attribute.name.to_s.match?(/\A(views|visits|clicks)\z/i) -%>
|
236
|
+
<%= singular_table_name %>_attributes[:<%= attribute.name %>] = rand(0..10000)
|
237
|
+
<% else -%>
|
238
|
+
<%= singular_table_name %>_attributes[:<%= attribute.name %>] = rand(1..1000)
|
239
|
+
<% end -%>
|
240
|
+
<% elsif attribute.type == :decimal || attribute.type == :float -%>
|
241
|
+
<% if attribute.name.to_s.match?(/\A(price|cost|amount|total|fee)\z/i) -%>
|
242
|
+
<%= singular_table_name %>_attributes[:<%= attribute.name %>] = Faker::Commerce.price(range: 0.99..999.99)
|
243
|
+
<% elsif attribute.name.to_s.match?(/\A(latitude)\z/i) -%>
|
244
|
+
<%= singular_table_name %>_attributes[:<%= attribute.name %>] = Faker::Address.latitude
|
245
|
+
<% elsif attribute.name.to_s.match?(/\A(longitude)\z/i) -%>
|
246
|
+
<%= singular_table_name %>_attributes[:<%= attribute.name %>] = Faker::Address.longitude
|
247
|
+
<% elsif attribute.name.to_s.match?(/\A(rating|score)\z/i) -%>
|
248
|
+
<%= singular_table_name %>_attributes[:<%= attribute.name %>] = rand(1.0..5.0).round(1)
|
249
|
+
<% elsif attribute.name.to_s.match?(/\A(percentage|percent)\z/i) -%>
|
250
|
+
<%= singular_table_name %>_attributes[:<%= attribute.name %>] = rand(0.0..100.0).round(2)
|
251
|
+
<% elsif attribute.name.to_s.match?(/\A(weight)\z/i) -%>
|
252
|
+
<%= singular_table_name %>_attributes[:<%= attribute.name %>] = rand(0.1..100.0).round(2)
|
253
|
+
<% elsif attribute.name.to_s.match?(/\A(height|width|length|depth)\z/i) -%>
|
254
|
+
<%= singular_table_name %>_attributes[:<%= attribute.name %>] = rand(1.0..500.0).round(2)
|
255
|
+
<% else -%>
|
256
|
+
<%= singular_table_name %>_attributes[:<%= attribute.name %>] = rand(1.0..100.0).round(2)
|
257
|
+
<% end -%>
|
258
|
+
<% elsif attribute.type == :boolean -%>
|
259
|
+
<% if attribute.name.to_s.match?(/\A(active|enabled|published|visible|confirmed|verified|featured)\z/i) -%>
|
260
|
+
<%= singular_table_name %>_attributes[:<%= attribute.name %>] = [true, true, true, false].sample # 75% true
|
261
|
+
<% elsif attribute.name.to_s.match?(/\A(archived|deleted|disabled|hidden|locked|suspended)\z/i) -%>
|
262
|
+
<%= singular_table_name %>_attributes[:<%= attribute.name %>] = [false, false, false, true].sample # 25% true
|
263
|
+
<% else -%>
|
264
|
+
<%= singular_table_name %>_attributes[:<%= attribute.name %>] = [true, false].sample
|
265
|
+
<% end -%>
|
266
|
+
<% elsif attribute.type == :date -%>
|
267
|
+
<%= singular_table_name %>_attributes[:<%= attribute.name %>] = Faker::Date.between(from: 2.years.ago, to: 1.year.from_now)
|
268
|
+
<% elsif attribute.type == :datetime || attribute.type == :timestamp -%>
|
269
|
+
<% if attribute.name.to_s.match?(/\A(published_at|released_at|launched_at)\z/i) -%>
|
270
|
+
<%= singular_table_name %>_attributes[:<%= attribute.name %>] = Faker::Time.between(from: 6.months.ago, to: Time.current)
|
271
|
+
<% elsif attribute.name.to_s.match?(/\A(expires_at|ends_at|deadline)\z/i) -%>
|
272
|
+
<%= singular_table_name %>_attributes[:<%= attribute.name %>] = Faker::Time.between(from: Time.current, to: 1.year.from_now)
|
273
|
+
<% else -%>
|
274
|
+
<%= singular_table_name %>_attributes[:<%= attribute.name %>] = Faker::Time.between(from: 1.year.ago, to: Time.current)
|
275
|
+
<% end -%>
|
276
|
+
<% elsif attribute.type == :time -%>
|
277
|
+
<%= singular_table_name %>_attributes[:<%= attribute.name %>] = Faker::Time.between(from: Date.current.beginning_of_day, to: Date.current.end_of_day).strftime("%H:%M:%S")
|
278
|
+
<% else -%>
|
279
|
+
<%= singular_table_name %>_attributes[:<%= attribute.name %>] = Faker::Lorem.word
|
280
|
+
<% end -%>
|
281
|
+
<% end -%>
|
282
|
+
|
283
|
+
<%= table_name %>_data << <%= singular_table_name %>_attributes
|
284
|
+
end
|
285
|
+
|
286
|
+
# Create <%= table_name %> in batches for better performance
|
287
|
+
<%= table_name %>_data.each_slice(10) do |batch|
|
288
|
+
batch.each do |attributes|
|
289
|
+
begin
|
290
|
+
<%= class_name %>.create!(attributes)
|
291
|
+
rescue ActiveRecord::RecordInvalid => e
|
292
|
+
puts "โ ๏ธ Skipped invalid <%= singular_table_name %>: #{e.message}"
|
293
|
+
rescue => e
|
294
|
+
puts "โ Error creating <%= singular_table_name %>: #{e.message}"
|
295
|
+
end
|
296
|
+
end
|
297
|
+
print "."
|
298
|
+
end
|
299
|
+
|
300
|
+
puts "\nโ
Created #{<%= class_name %>.count} <%= table_name %>"
|
301
|
+
|
302
|
+
# Create some specific test scenarios for better test coverage
|
303
|
+
puts "๐ฏ Creating specific test scenarios..."
|
304
|
+
|
305
|
+
# Create some <%= table_name %> with edge case data
|
306
|
+
<% unless options[:skip_tenancy] -%>
|
307
|
+
organizations.each do |org|
|
308
|
+
agency = agencies.where(organization: org).sample
|
309
|
+
<% if attributes.any? { |attr| attr.type == :references && attr.name.to_s.match?(/user/) } -%>
|
310
|
+
user = users.where(organization: org).sample
|
311
|
+
<% end -%>
|
312
|
+
|
313
|
+
# Create a minimal <%= singular_table_name %> (only required fields)
|
314
|
+
minimal_<%= singular_table_name %> = {}
|
315
|
+
|
316
|
+
# Multi-tenancy: Always assign organization (required) and agency (optional)
|
317
|
+
minimal_<%= singular_table_name %>[:organization] = org
|
318
|
+
minimal_<%= singular_table_name %>[:agency] = agency
|
319
|
+
|
320
|
+
# Assign additional reference attributes dynamically
|
321
|
+
<% attributes.select { |attr| attr.type == :references }.each do |reference| -%>
|
322
|
+
<% # Skip organization and agency if tenancy is included (they're already assigned above) -%>
|
323
|
+
<% unless reference.name == 'organization' || reference.name == 'agency' -%>
|
324
|
+
<% if reference.name.to_s.match?(/user/) -%>
|
325
|
+
minimal_<%= singular_table_name %>[:<%= reference.name %>] = user
|
326
|
+
<% else -%>
|
327
|
+
# Handle other reference types as needed
|
328
|
+
# minimal_<%= singular_table_name %>[:<%= reference.name %>] = # TODO: Assign appropriate value
|
329
|
+
<% end -%>
|
330
|
+
<% end -%>
|
331
|
+
<% end -%>
|
332
|
+
|
333
|
+
<% attributes.reject { |attr| attr.type == :references }.each do |attribute| -%>
|
334
|
+
<% if attribute.required? -%>
|
335
|
+
<% if attribute.type == :string -%>
|
336
|
+
minimal_<%= singular_table_name %>[:<%= attribute.name %>] = "Minimal <%= attribute.name.humanize %>"
|
337
|
+
<% elsif attribute.type == :text -%>
|
338
|
+
minimal_<%= singular_table_name %>[:<%= attribute.name %>] = "Minimal <%= attribute.name.humanize %> content"
|
339
|
+
<% elsif attribute.type == :integer -%>
|
340
|
+
minimal_<%= singular_table_name %>[:<%= attribute.name %>] = 1
|
341
|
+
<% elsif attribute.type == :decimal || attribute.type == :float -%>
|
342
|
+
minimal_<%= singular_table_name %>[:<%= attribute.name %>] = 1.0
|
343
|
+
<% elsif attribute.type == :boolean -%>
|
344
|
+
minimal_<%= singular_table_name %>[:<%= attribute.name %>] = true
|
345
|
+
<% elsif attribute.type == :date -%>
|
346
|
+
minimal_<%= singular_table_name %>[:<%= attribute.name %>] = Date.current
|
347
|
+
<% elsif attribute.type == :datetime || attribute.type == :timestamp -%>
|
348
|
+
minimal_<%= singular_table_name %>[:<%= attribute.name %>] = Time.current
|
349
|
+
<% elsif attribute.type == :time -%>
|
350
|
+
minimal_<%= singular_table_name %>[:<%= attribute.name %>] = Time.current.strftime("%H:%M:%S")
|
351
|
+
<% else -%>
|
352
|
+
minimal_<%= singular_table_name %>[:<%= attribute.name %>] = "minimal"
|
353
|
+
<% end -%>
|
354
|
+
<% end -%>
|
355
|
+
<% end -%>
|
356
|
+
|
357
|
+
begin
|
358
|
+
<%= class_name %>.create!(minimal_<%= singular_table_name %>)
|
359
|
+
rescue ActiveRecord::RecordInvalid => e
|
360
|
+
puts "โ ๏ธ Skipped minimal <%= singular_table_name %>: #{e.message}"
|
361
|
+
end
|
362
|
+
|
363
|
+
<% if attributes.any? { |attr| attr.name.to_s.match?(/\A(active|enabled|published|visible|status|state)\z/i) } -%>
|
364
|
+
# Create <%= table_name %> with different states for testing filters
|
365
|
+
<% attributes.each do |attribute| -%>
|
366
|
+
<% if attribute.name.to_s.match?(/\A(status|state)\z/i) && attribute.type == :string -%>
|
367
|
+
%w[active inactive pending archived draft].each do |status|
|
368
|
+
status_<%= singular_table_name %> = minimal_<%= singular_table_name %>.dup
|
369
|
+
status_<%= singular_table_name %>[:<%= attribute.name %>] = status
|
370
|
+
<%= class_name %>.create!(status_<%= singular_table_name %>) rescue nil
|
371
|
+
end
|
372
|
+
<% elsif attribute.name.to_s.match?(/\A(active|enabled|published|visible)\z/i) && attribute.type == :boolean -%>
|
373
|
+
[true, false].each do |state|
|
374
|
+
state_<%= singular_table_name %> = minimal_<%= singular_table_name %>.dup
|
375
|
+
state_<%= singular_table_name %>[:<%= attribute.name %>] = state
|
376
|
+
<%= class_name %>.create!(state_<%= singular_table_name %>) rescue nil
|
377
|
+
end
|
378
|
+
<% end -%>
|
379
|
+
<% end -%>
|
380
|
+
<% end -%>
|
381
|
+
end
|
382
|
+
<% else -%>
|
383
|
+
3.times do
|
384
|
+
# Create a minimal <%= singular_table_name %> (only required fields)
|
385
|
+
minimal_<%= singular_table_name %> = {}
|
386
|
+
|
387
|
+
# Assign reference attributes dynamically
|
388
|
+
<% attributes.select { |attr| attr.type == :references }.each do |reference| -%>
|
389
|
+
<% if reference.name.to_s.match?(/user/) -%>
|
390
|
+
minimal_<%= singular_table_name %>[:<%= reference.name %>] = users.sample if users.any?
|
391
|
+
<% else -%>
|
392
|
+
# Handle other reference types as needed
|
393
|
+
# minimal_<%= singular_table_name %>[:<%= reference.name %>] = # TODO: Assign appropriate value
|
394
|
+
<% end -%>
|
395
|
+
<% end -%>
|
396
|
+
|
397
|
+
<% attributes.reject { |attr| attr.type == :references }.each do |attribute| -%>
|
398
|
+
<% if attribute.required? -%>
|
399
|
+
<% if attribute.type == :string -%>
|
400
|
+
minimal_<%= singular_table_name %>[:<%= attribute.name %>] = "Minimal <%= attribute.name.humanize %>"
|
401
|
+
<% elsif attribute.type == :text -%>
|
402
|
+
minimal_<%= singular_table_name %>[:<%= attribute.name %>] = "Minimal <%= attribute.name.humanize %> content"
|
403
|
+
<% elsif attribute.type == :integer -%>
|
404
|
+
minimal_<%= singular_table_name %>[:<%= attribute.name %>] = 1
|
405
|
+
<% elsif attribute.type == :decimal || attribute.type == :float -%>
|
406
|
+
minimal_<%= singular_table_name %>[:<%= attribute.name %>] = 1.0
|
407
|
+
<% elsif attribute.type == :boolean -%>
|
408
|
+
minimal_<%= singular_table_name %>[:<%= attribute.name %>] = true
|
409
|
+
<% elsif attribute.type == :date -%>
|
410
|
+
minimal_<%= singular_table_name %>[:<%= attribute.name %>] = Date.current
|
411
|
+
<% elsif attribute.type == :datetime || attribute.type == :timestamp -%>
|
412
|
+
minimal_<%= singular_table_name %>[:<%= attribute.name %>] = Time.current
|
413
|
+
<% elsif attribute.type == :time -%>
|
414
|
+
minimal_<%= singular_table_name %>[:<%= attribute.name %>] = Time.current.strftime("%H:%M:%S")
|
415
|
+
<% else -%>
|
416
|
+
minimal_<%= singular_table_name %>[:<%= attribute.name %>] = "minimal"
|
417
|
+
<% end -%>
|
418
|
+
<% end -%>
|
419
|
+
<% end -%>
|
420
|
+
|
421
|
+
begin
|
422
|
+
<%= class_name %>.create!(minimal_<%= singular_table_name %>)
|
423
|
+
rescue ActiveRecord::RecordInvalid => e
|
424
|
+
puts "โ ๏ธ Skipped minimal <%= singular_table_name %>: #{e.message}"
|
425
|
+
end
|
426
|
+
|
427
|
+
<% if attributes.any? { |attr| attr.name.to_s.match?(/\A(active|enabled|published|visible|status|state)\z/i) } -%>
|
428
|
+
# Create <%= table_name %> with different states for testing filters
|
429
|
+
<% attributes.each do |attribute| -%>
|
430
|
+
<% if attribute.name.to_s.match?(/\A(status|state)\z/i) && attribute.type == :string -%>
|
431
|
+
%w[active inactive pending archived draft].each do |status|
|
432
|
+
status_<%= singular_table_name %> = minimal_<%= singular_table_name %>.dup
|
433
|
+
status_<%= singular_table_name %>[:<%= attribute.name %>] = status
|
434
|
+
<%= class_name %>.create!(status_<%= singular_table_name %>) rescue nil
|
435
|
+
end
|
436
|
+
<% elsif attribute.name.to_s.match?(/\A(active|enabled|published|visible)\z/i) && attribute.type == :boolean -%>
|
437
|
+
[true, false].each do |state|
|
438
|
+
state_<%= singular_table_name %> = minimal_<%= singular_table_name %>.dup
|
439
|
+
state_<%= singular_table_name %>[:<%= attribute.name %>] = state
|
440
|
+
<%= class_name %>.create!(state_<%= singular_table_name %>) rescue nil
|
441
|
+
end
|
442
|
+
<% end -%>
|
443
|
+
<% end -%>
|
444
|
+
<% end -%>
|
445
|
+
end
|
446
|
+
<% end -%>
|
447
|
+
|
448
|
+
puts "โ
Created test scenario <%= table_name %>"
|
449
|
+
|
450
|
+
# Summary
|
451
|
+
total_<%= table_name %> = <%= class_name %>.count
|
452
|
+
fixture_<%= table_name %> = fixture_count || 0
|
453
|
+
faker_<%= table_name %> = total_<%= table_name %> - fixture_<%= table_name %>
|
454
|
+
|
455
|
+
puts "\n๐ Seeding complete!"
|
456
|
+
puts "๐ Summary:"
|
457
|
+
puts " โข Total <%= table_name %>: #{total_<%= table_name %>}"
|
458
|
+
puts " โข โโโ Fixture <%= table_name %>: #{fixture_<%= table_name %>} (same as test data)"
|
459
|
+
puts " โข โโโ Faker <%= table_name %>: #{faker_<%= table_name %>} (realistic dev data)"
|
460
|
+
<% unless options[:skip_tenancy] -%>
|
461
|
+
puts " โข Organizations: #{Organization.count}"
|
462
|
+
puts " โข Agencies: #{Agency.count}"
|
463
|
+
puts " โข <%= table_name %> per organization: #{(total_<%= table_name %>.to_f / Organization.count).round(1)} avg"
|
464
|
+
<% end -%>
|
465
|
+
<% if attributes.any? { |attr| attr.type == :references && attr.name.to_s.match?(/user/) } -%>
|
466
|
+
puts " โข Users: #{User.count}"
|
467
|
+
<% end -%>
|
468
|
+
|
469
|
+
puts "\n๐ก Development Benefits:"
|
470
|
+
puts " โข Tests and development use the same baseline fixture data"
|
471
|
+
puts " โข Rich Faker data provides realistic content for evaluation"
|
472
|
+
puts " โข Fixture data is predictable and referenceable in tests"
|
473
|
+
|
474
|
+
<% if attributes.any? { |attr| attr.name.to_s.match?(/\A(status|state|active|enabled|published|visible)\z/i) } -%>
|
475
|
+
# Show distribution for better understanding
|
476
|
+
<% attributes.each do |attribute| -%>
|
477
|
+
<% if attribute.name.to_s.match?(/\A(status|state)\z/i) && attribute.type == :string -%>
|
478
|
+
puts "\n๐ <%= attribute.name.humanize %> distribution:"
|
479
|
+
<%= class_name %>.group(:<%= attribute.name %>).count.each do |status, count|
|
480
|
+
percentage = (count.to_f / total_<%= table_name %> * 100).round(1)
|
481
|
+
puts " โข #{status}: #{count} (#{percentage}%)"
|
482
|
+
end
|
483
|
+
<% elsif attribute.name.to_s.match?(/\A(active|enabled|published|visible)\z/i) && attribute.type == :boolean -%>
|
484
|
+
puts "\n๐ <%= attribute.name.humanize %> distribution:"
|
485
|
+
<%= class_name %>.group(:<%= attribute.name %>).count.each do |state, count|
|
486
|
+
percentage = (count.to_f / total_<%= table_name %> * 100).round(1)
|
487
|
+
puts " โข #{state ? 'Yes' : 'No'}: #{count} (#{percentage}%)"
|
488
|
+
end
|
489
|
+
<% end -%>
|
490
|
+
<% end -%>
|
491
|
+
<% end -%>
|
492
|
+
|
493
|
+
puts "\n๐ฑ <%= class_name %> seeding complete!"
|