brick 1.0.4 → 1.0.5
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 +4 -4
- data/lib/brick/config.rb +9 -0
- data/lib/brick/extensions.rb +38 -16
- data/lib/brick/frameworks/rails/engine.rb +92 -117
- data/lib/brick/version_number.rb +1 -1
- data/lib/brick.rb +46 -2
- data/lib/generators/brick/install_generator.rb +8 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9cd49783dae6701760920fe007cbde7382fd3dbaf5e8f7472d475c0fe8aaf660
|
4
|
+
data.tar.gz: d2330f28e87dde00b1377f6cbca31cbbfe2dd3b2c495f1fbd0aebc0f8a951504
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2a3c7ba47d32f3a6ab6c9be838006826f5266efb1349d90ce7d53b5e8f89ea078bdcb699a7db8084176e2de444a27931ce8e0216af666c25704c0568b59ac827
|
7
|
+
data.tar.gz: 41fccf3387315cd54fd596955c3f07760941cd4aa51959dc99f87d0b6fb38de742ad11fe7dabb084a3e72167c340b8aafce838c7704626359ccb41878e202ae2
|
data/lib/brick/config.rb
CHANGED
@@ -65,6 +65,15 @@ module Brick
|
|
65
65
|
@mutex.synchronize { @additional_references = references }
|
66
66
|
end
|
67
67
|
|
68
|
+
# Associations to treat has a has_one
|
69
|
+
def has_ones
|
70
|
+
@mutex.synchronize { @has_ones }
|
71
|
+
end
|
72
|
+
|
73
|
+
def has_ones=(references)
|
74
|
+
@mutex.synchronize { @has_ones = references }
|
75
|
+
end
|
76
|
+
|
68
77
|
def skip_database_views
|
69
78
|
@mutex.synchronize { @skip_database_views }
|
70
79
|
end
|
data/lib/brick/extensions.rb
CHANGED
@@ -61,14 +61,15 @@ module ActiveRecord
|
|
61
61
|
wheres = {}
|
62
62
|
rel_joins = []
|
63
63
|
params.each do |k, v|
|
64
|
-
|
64
|
+
case (ks = k.split('.')).length
|
65
|
+
when 1
|
66
|
+
next unless klass._brick_get_fks.include?(k)
|
67
|
+
when 2
|
65
68
|
assoc_name = ks.first.to_sym
|
66
69
|
# Make sure it's a good association name and that the model has that column name
|
67
70
|
next unless klass.reflect_on_association(assoc_name)&.klass&.columns&.map(&:name)&.include?(ks.last)
|
68
71
|
|
69
72
|
rel_joins << assoc_name unless rel_joins.include?(assoc_name)
|
70
|
-
else
|
71
|
-
next unless klass._brick_get_fks.include?(k)
|
72
73
|
end
|
73
74
|
wheres[k] = v.split(',')
|
74
75
|
end
|
@@ -184,6 +185,14 @@ class Object
|
|
184
185
|
need_class_name = singular_table_name.underscore != assoc_name
|
185
186
|
need_fk = "#{assoc_name}_id" != assoc[:fk]
|
186
187
|
inverse_assoc_name, _x = _brick_get_hm_assoc_name(relations[assoc[:inverse_table]], assoc[:inverse])
|
188
|
+
if (has_ones = ::Brick.config.has_ones.fetch(assoc[:inverse][:alternate_name].camelize, nil))&.key?(singular_inv_assoc_name = ActiveSupport::Inflector.singularize(inverse_assoc_name))
|
189
|
+
inverse_assoc_name = if has_ones[singular_inv_assoc_name]
|
190
|
+
need_inverse_of = true
|
191
|
+
has_ones[singular_inv_assoc_name]
|
192
|
+
else
|
193
|
+
singular_inv_assoc_name
|
194
|
+
end
|
195
|
+
end
|
187
196
|
:belongs_to
|
188
197
|
else
|
189
198
|
# need_class_name = ActiveSupport::Inflector.singularize(assoc_name) == ActiveSupport::Inflector.singularize(table_name.underscore)
|
@@ -191,14 +200,23 @@ class Object
|
|
191
200
|
assoc_name, need_class_name = _brick_get_hm_assoc_name(relation, assoc)
|
192
201
|
need_fk = "#{ActiveSupport::Inflector.singularize(assoc[:inverse][:inverse_table])}_id" != assoc[:fk]
|
193
202
|
# fks[table_name].find { |other_assoc| other_assoc.object_id != assoc.object_id && other_assoc[:assoc_name] == assoc[assoc_name] }
|
194
|
-
|
203
|
+
if (has_ones = ::Brick.config.has_ones&.fetch(model_name, nil))&.key?(singular_assoc_name = ActiveSupport::Inflector.singularize(assoc_name))
|
204
|
+
assoc_name = if has_ones[singular_assoc_name]
|
205
|
+
need_class_name = true
|
206
|
+
has_ones[singular_assoc_name]
|
207
|
+
else
|
208
|
+
singular_assoc_name
|
209
|
+
end
|
210
|
+
:has_one
|
211
|
+
else
|
212
|
+
:has_many
|
213
|
+
end
|
195
214
|
end
|
215
|
+
# Figure out if we need to specially call out the class_name and/or foreign key
|
216
|
+
# (and if either of those then definitely also a specific inverse_of)
|
196
217
|
options[:class_name] = singular_table_name.camelize if need_class_name
|
197
|
-
|
198
|
-
if
|
199
|
-
options[:foreign_key] = assoc[:fk].to_sym
|
200
|
-
end
|
201
|
-
options[:inverse_of] = inverse_assoc_name.to_sym if need_class_name || need_fk
|
218
|
+
options[:foreign_key] = assoc[:fk].to_sym if need_fk # Funky foreign key?
|
219
|
+
options[:inverse_of] = inverse_assoc_name.to_sym if need_class_name || need_fk || need_inverse_of
|
202
220
|
assoc_name = assoc_name.to_sym
|
203
221
|
code << " #{macro} #{assoc_name.inspect}#{options.map { |k, v| ", #{k}: #{v.inspect}" }.join}\n"
|
204
222
|
self.send(macro, assoc_name, **options)
|
@@ -273,9 +291,13 @@ end
|
|
273
291
|
module ActiveRecord::ConnectionHandling
|
274
292
|
alias _brick_establish_connection establish_connection
|
275
293
|
def establish_connection(*args)
|
276
|
-
|
294
|
+
conn = _brick_establish_connection(*args)
|
295
|
+
_brick_reflect_tables
|
296
|
+
conn
|
297
|
+
end
|
277
298
|
|
278
|
-
|
299
|
+
def _brick_reflect_tables
|
300
|
+
if (relations = ::Brick.relations).empty?
|
279
301
|
# Only for Postgres? (Doesn't work in sqlite3)
|
280
302
|
# puts ActiveRecord::Base.connection.execute("SELECT current_setting('SEARCH_PATH')").to_a.inspect
|
281
303
|
|
@@ -367,7 +389,7 @@ module ActiveRecord::ConnectionHandling
|
|
367
389
|
case ActiveRecord::Base.connection.adapter_name
|
368
390
|
when 'PostgreSQL', 'Mysql2'
|
369
391
|
sql = ActiveRecord::Base.send(:sanitize_sql_array, [
|
370
|
-
"SELECT kcu1.TABLE_NAME, kcu1.COLUMN_NAME, kcu2.TABLE_NAME, kcu1.CONSTRAINT_NAME
|
392
|
+
"SELECT kcu1.TABLE_NAME, kcu1.COLUMN_NAME, kcu2.TABLE_NAME AS primary_table, kcu1.CONSTRAINT_NAME
|
371
393
|
FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS AS rc
|
372
394
|
INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE AS kcu1
|
373
395
|
ON kcu1.CONSTRAINT_CATALOG = rc.CONSTRAINT_CATALOG
|
@@ -389,9 +411,10 @@ module ActiveRecord::ConnectionHandling
|
|
389
411
|
else
|
390
412
|
end
|
391
413
|
if sql
|
392
|
-
|
393
|
-
|
394
|
-
|
414
|
+
ActiveRecord::Base.connection.execute(sql).each do |fk|
|
415
|
+
fk = fk.values unless fk.is_a?(Array)
|
416
|
+
::Brick._add_bt_and_hm(fk, relations)
|
417
|
+
end
|
395
418
|
end
|
396
419
|
end
|
397
420
|
|
@@ -403,7 +426,6 @@ module ActiveRecord::ConnectionHandling
|
|
403
426
|
|
404
427
|
# relations.keys.each { |k| ActiveSupport::Inflector.singularize(k).camelize.constantize }
|
405
428
|
# Layout table describes permissioned hierarchy throughout
|
406
|
-
x
|
407
429
|
end
|
408
430
|
end
|
409
431
|
|
@@ -5,11 +5,8 @@ module Brick
|
|
5
5
|
# See http://guides.rubyonrails.org/engines.html
|
6
6
|
class Engine < ::Rails::Engine
|
7
7
|
# paths['app/models'] << 'lib/brick/frameworks/active_record/models'
|
8
|
-
puts "BEFORE - engine set config"
|
9
8
|
config.brick = ActiveSupport::OrderedOptions.new
|
10
|
-
# initializer 'brick.initialisation' do |app|
|
11
9
|
ActiveSupport.on_load(:before_initialize) do |app|
|
12
|
-
puts "BEFORE - engine initialisation"
|
13
10
|
::Brick.enable_models = app.config.brick.fetch(:enable_models, true)
|
14
11
|
::Brick.enable_controllers = app.config.brick.fetch(:enable_controllers, true)
|
15
12
|
::Brick.enable_views = app.config.brick.fetch(:enable_views, true)
|
@@ -25,83 +22,66 @@ module Brick
|
|
25
22
|
# Additional references (virtual foreign keys)
|
26
23
|
::Brick.additional_references = app.config.brick.fetch(:additional_references, nil)
|
27
24
|
|
28
|
-
#
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
25
|
+
# Has one relationships
|
26
|
+
::Brick.has_ones = app.config.brick.fetch(:has_ones, nil)
|
27
|
+
end
|
28
|
+
|
29
|
+
# After we're initialized and before running the rest of stuff, put our configuration in place
|
30
|
+
ActiveSupport.on_load(:after_initialize) do
|
31
|
+
# ====================================
|
32
|
+
# Dynamically create generic templates
|
33
|
+
# ====================================
|
34
|
+
if ::Brick.enable_views?
|
35
|
+
ActionView::LookupContext.class_exec do
|
36
|
+
alias :_brick_template_exists? :template_exists?
|
37
|
+
def template_exists?(*args, **options)
|
38
|
+
unless (is_template_exists = _brick_template_exists?(*args, **options))
|
39
|
+
# Need to return true if we can fill in the blanks for a missing one
|
40
|
+
# args will be something like: ["index", ["categories"]]
|
41
|
+
model = args[1].map(&:camelize).join('::').singularize.constantize
|
42
|
+
if (
|
43
|
+
is_template_exists = model && (
|
44
|
+
['index', 'show'].include?(args.first) || # Everything has index and show
|
45
|
+
# Only CRU stuff has create / update / destroy
|
46
|
+
(!model.is_view? && ['new', 'create', 'edit', 'update', 'destroy'].include?(args.first))
|
47
|
+
)
|
48
|
+
)
|
49
|
+
instance_variable_set(:@_brick_model, model)
|
51
50
|
end
|
52
|
-
is_template_exists
|
53
51
|
end
|
52
|
+
is_template_exists
|
53
|
+
end
|
54
54
|
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
end
|
77
|
-
end
|
78
|
-
|
79
|
-
s.first[a.foreign_key] = [a.name, a.klass]
|
80
|
-
when :has_many
|
81
|
-
s.last[a.name] = a
|
82
|
-
end
|
83
|
-
s
|
84
|
-
end
|
85
|
-
# Weed out has_manys that go to an associative table
|
86
|
-
associatives = hms.select { |k, v| v.options[:through] }.each_with_object({}) do |hmt, s|
|
87
|
-
s[hmt.first] = hms.delete(hmt.last.options[:through]) # End up with a hash of HMT names pointing to join-table associations
|
55
|
+
alias :_brick_find_template :find_template
|
56
|
+
def find_template(*args, **options)
|
57
|
+
if @_brick_model
|
58
|
+
model_name = @_brick_model.name
|
59
|
+
pk = @_brick_model.primary_key
|
60
|
+
obj_name = model_name.underscore
|
61
|
+
table_name = model_name.pluralize.underscore
|
62
|
+
# This gets has_many as well as has_many :through
|
63
|
+
# %%% weed out ones that don't have an available model to reference
|
64
|
+
bts, hms = ::Brick.get_bts_and_hms(@_brick_model)
|
65
|
+
# Weed out has_manys that go to an associative table
|
66
|
+
associatives = hms.select { |k, v| v.options[:through] }.each_with_object({}) do |hmt, s|
|
67
|
+
s[hmt.first] = hms.delete(hmt.last.options[:through]) # End up with a hash of HMT names pointing to join-table associations
|
68
|
+
end
|
69
|
+
hms_headers = hms.each_with_object(+'') { |hm, s| s << "<th>HM#{'T' if hm.last.options[:through]} #{hm.first}</th>\n" }
|
70
|
+
hms_columns = hms.each_with_object(+'') do |hm, s|
|
71
|
+
hm_fk_name = if hm.last.options[:through]
|
72
|
+
associative = associatives[hm.last.name]
|
73
|
+
"'#{associative.name}.#{associative.foreign_key}'"
|
74
|
+
else
|
75
|
+
hm.last.foreign_key
|
88
76
|
end
|
89
|
-
|
90
|
-
|
91
|
-
hm_fk_name = if hm.last.options[:through]
|
92
|
-
associative = associatives[hm.last.name]
|
93
|
-
"'#{associative.name}.#{associative.foreign_key}'"
|
94
|
-
else
|
95
|
-
hm.last.foreign_key
|
96
|
-
end
|
97
|
-
s << "<td>
|
98
|
-
<%= link_to \"#\{#{obj_name}.#{hm.first}.count\} #{hm.first}\", #{hm.last.klass.name.underscore.pluralize}_path({ #{hm_fk_name}: #{obj_name}.#{pk} }) %>
|
77
|
+
s << "<td>
|
78
|
+
<%= link_to \"#\{#{obj_name}.#{hm.first}.count\} #{hm.first}\", #{hm.last.klass.name.underscore.pluralize}_path({ #{hm_fk_name}: #{obj_name}.#{pk} }) unless #{obj_name}.#{hm.first}.count.zero? %>
|
99
79
|
</td>\n"
|
100
|
-
|
80
|
+
end
|
101
81
|
|
102
|
-
|
103
|
-
|
104
|
-
|
82
|
+
inline = case args.first
|
83
|
+
when 'index'
|
84
|
+
"<p style=\"color: green\"><%= notice %></p>
|
105
85
|
|
106
86
|
<h1>#{model_name.pluralize}</h1>
|
107
87
|
<% if @_brick_params&.present? %><h3>where <%= @_brick_params.each_with_object([]) { |v, s| s << \"#\{v.first\} = #\{v.last.inspect\}\" }.join(', ') %></h3><% end %>
|
@@ -161,63 +141,58 @@ module Brick
|
|
161
141
|
|
162
142
|
#{"<hr><%= link_to \"New #{obj_name}\", new_#{obj_name}_path %>" unless @_brick_model.is_view?}
|
163
143
|
"
|
164
|
-
|
165
|
-
|
166
|
-
end
|
167
|
-
# As if it were an inline template (see #determine_template in actionview-5.2.6.2/lib/action_view/renderer/template_renderer.rb)
|
168
|
-
keys = options.has_key?(:locals) ? options[:locals].keys : []
|
169
|
-
handler = ActionView::Template.handler_for_extension(options[:type] || 'erb')
|
170
|
-
ActionView::Template.new(inline, "auto-generated #{args.first} template", handler, locals: keys)
|
171
|
-
else
|
172
|
-
_brick_find_template(*args, **options)
|
144
|
+
when 'show'
|
145
|
+
"<%= @#{@_brick_model.name.underscore}.inspect %>"
|
173
146
|
end
|
147
|
+
# As if it were an inline template (see #determine_template in actionview-5.2.6.2/lib/action_view/renderer/template_renderer.rb)
|
148
|
+
keys = options.has_key?(:locals) ? options[:locals].keys : []
|
149
|
+
handler = ActionView::Template.handler_for_extension(options[:type] || 'erb')
|
150
|
+
ActionView::Template.new(inline, "auto-generated #{args.first} template", handler, locals: keys)
|
151
|
+
else
|
152
|
+
_brick_find_template(*args, **options)
|
174
153
|
end
|
175
154
|
end
|
176
155
|
end
|
156
|
+
end
|
177
157
|
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
send(:resources, controller_name.to_sym, **options)
|
193
|
-
end
|
158
|
+
if ::Brick.enable_routes?
|
159
|
+
ActionDispatch::Routing::RouteSet.class_exec do
|
160
|
+
alias _brick_finalize_routeset! finalize!
|
161
|
+
def finalize!(*args, **options)
|
162
|
+
unless @finalized
|
163
|
+
existing_controllers = routes.each_with_object({}) { |r, s| c = r.defaults[:controller]; s[c] = nil if c }
|
164
|
+
::Rails.application.routes.append do
|
165
|
+
# %%% TODO: If no auto-controllers then enumerate the controllers folder in order to build matching routes
|
166
|
+
# If auto-controllers and auto-models are both enabled then this makes sense:
|
167
|
+
::Brick.relations.each do |k, v|
|
168
|
+
unless existing_controllers.key?(controller_name = k.underscore.pluralize)
|
169
|
+
options = {}
|
170
|
+
options[:only] = [:index, :show] if v.key?(:isView)
|
171
|
+
send(:resources, controller_name.to_sym, **options)
|
194
172
|
end
|
195
173
|
end
|
196
174
|
end
|
197
|
-
_brick_finalize_routeset!(*args, **options)
|
198
175
|
end
|
176
|
+
_brick_finalize_routeset!(*args, **options)
|
199
177
|
end
|
200
178
|
end
|
179
|
+
end
|
201
180
|
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
ars = [ars] unless ars.empty? || ars.first.is_a?(Array)
|
207
|
-
ars.each do |fk|
|
208
|
-
::Brick._add_bt_and_hm(fk[0..2])
|
209
|
-
end
|
181
|
+
# Additional references (virtual foreign keys)
|
182
|
+
if (ars = ::Brick.config.additional_references)
|
183
|
+
ars.each do |fk|
|
184
|
+
::Brick._add_bt_and_hm(fk[0..2])
|
210
185
|
end
|
186
|
+
end
|
211
187
|
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
end
|
188
|
+
# Find associative tables that can be set up for has_many :through
|
189
|
+
::Brick.relations.each do |_key, tbl|
|
190
|
+
tbl_cols = tbl[:cols].keys
|
191
|
+
fks = tbl[:fks].each_with_object({}) { |fk, s| s[fk.last[:fk]] = fk.last[:inverse_table] if fk.last[:is_bt]; s }
|
192
|
+
# Aside from the primary key and the metadata columns created_at, updated_at, and deleted_at, if this table only has
|
193
|
+
# foreign keys then it can act as an associative table and thus be used with has_many :through.
|
194
|
+
if fks.length > 1 && (tbl_cols - fks.keys - (::Brick.config.metadata_columns || []) - (tbl[:pkey].values.first || [])).length.zero?
|
195
|
+
fks.each { |fk| tbl[:hmt_fks][fk.first] = fk.last }
|
221
196
|
end
|
222
197
|
end
|
223
198
|
end
|
data/lib/brick/version_number.rb
CHANGED
data/lib/brick.rb
CHANGED
@@ -90,6 +90,30 @@ module Brick
|
|
90
90
|
(connections[ActiveRecord::Base.connection_pool.object_id] ||= Hash.new { |h, k| h[k] = Hash.new { |h, k| h[k] = {} } })
|
91
91
|
end
|
92
92
|
|
93
|
+
def get_bts_and_hms(model)
|
94
|
+
model.reflect_on_all_associations.each_with_object([{}, {}]) do |a, s|
|
95
|
+
case a.macro
|
96
|
+
when :belongs_to
|
97
|
+
# Build #brick_descrip if needed
|
98
|
+
if a.klass.instance_methods(false).exclude?(:brick_descrip)
|
99
|
+
descrip_col = (a.klass.columns.map(&:name) - a.klass._brick_get_fks -
|
100
|
+
(::Brick.config.metadata_columns || []) -
|
101
|
+
[a.klass.primary_key]).first&.to_sym
|
102
|
+
if descrip_col
|
103
|
+
a.klass.define_method :brick_descrip do
|
104
|
+
send(descrip_col)
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
s.first[a.foreign_key] = [a.name, a.klass]
|
110
|
+
when :has_many
|
111
|
+
s.last[a.name] = a
|
112
|
+
end
|
113
|
+
s
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
93
117
|
# Switches Brick auto-models on or off, for all threads
|
94
118
|
# @api public
|
95
119
|
def enable_models=(value)
|
@@ -159,8 +183,28 @@ module Brick
|
|
159
183
|
|
160
184
|
# Additional table associations to use (Think of these as virtual foreign keys perhaps)
|
161
185
|
# @api public
|
162
|
-
def additional_references=(
|
163
|
-
|
186
|
+
def additional_references=(ars)
|
187
|
+
if ars
|
188
|
+
ars = ars.call if ars.is_a?(Proc)
|
189
|
+
ars = ars.to_a unless ars.is_a?(Array)
|
190
|
+
ars = [ars] unless ars.empty? || ars.first.is_a?(Array)
|
191
|
+
Brick.config.additional_references = ars
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
# Associations to treat has a has_one
|
196
|
+
# @api public
|
197
|
+
def has_ones=(hos)
|
198
|
+
if hos
|
199
|
+
hos = hos.call if hos.is_a?(Proc)
|
200
|
+
hos = hos.to_a unless hos.is_a?(Array)
|
201
|
+
hos = [hos] unless hos.empty? || hos.first.is_a?(Array)
|
202
|
+
# Translate to being nested hashes
|
203
|
+
Brick.config.has_ones = hos&.each_with_object(Hash.new { |h, k| h[k] = {} }) do |v, s|
|
204
|
+
s[v.first][v[1]] = v[2] if v[1]
|
205
|
+
s
|
206
|
+
end
|
207
|
+
end
|
164
208
|
end
|
165
209
|
|
166
210
|
|
@@ -48,6 +48,14 @@ module Brick
|
|
48
48
|
# Brick.additional_references = [['orders', 'customer_id', 'customer'],
|
49
49
|
# ['customer', 'region_id', 'regions']]
|
50
50
|
|
51
|
+
# # By default primary tables involved in a foreign key relationship will indicate a \"has_many\" relationship pointing
|
52
|
+
# # back to the foreign table. In order to represent a \"has_one\" association instead, an override can be provided
|
53
|
+
# # using the primary model name and the association name which you instead want to have treated as a \"has_one\":
|
54
|
+
# Brick.has_ones = [['User', 'user_profile']]
|
55
|
+
# # If you want to use an alternate name for the \"has_one\", such as in the case above calling the association \"profile\"
|
56
|
+
# # instead of \"user_profile\", then apply that as a third parameter like this:
|
57
|
+
# Brick.has_ones = [['User', 'user_profile', 'profile']]
|
58
|
+
|
51
59
|
# # We normally don't consider the timestamp columns \"created_at\", \"updated_at\", and \"deleted_at\" to count when
|
52
60
|
# # finding tables which can serve as associative tables in an N:M association. That is, ones that can be a
|
53
61
|
# # part of a has_many :through association. If you want to use different exclusion columns than our defaults
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: brick
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Lorin Thwaits
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-03-
|
11
|
+
date: 2022-03-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|