brick 1.0.4 → 1.0.5
Sign up to get free protection for your applications and to get access to all the features.
- 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
|