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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: fe6bf3e38aef34261d9398b25f804504e7152721673b0534253c4284c9018013
4
- data.tar.gz: 766af0df2edc3dc8c8c73a5d1ecd99c8d738ed7cd00fc21c79c38ac3db991819
3
+ metadata.gz: 9cd49783dae6701760920fe007cbde7382fd3dbaf5e8f7472d475c0fe8aaf660
4
+ data.tar.gz: d2330f28e87dde00b1377f6cbca31cbbfe2dd3b2c495f1fbd0aebc0f8a951504
5
5
  SHA512:
6
- metadata.gz: 40f2eacaf7fada3056f5bfc701b01441ad02e34e76e87dc8e53b36a546c87216e8a319c3f0763b8fecff49344224d5660ff5b875937a3e30e2e7c80c662f684c
7
- data.tar.gz: 7901020af2ec1759c27c16a0c3a3ffbcddcd09691c652c14c02781823964e36409533afc562fb0d9beb508cc3329b601d6fe8c266c101f6db6d93aad5e055a3e
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
@@ -61,14 +61,15 @@ module ActiveRecord
61
61
  wheres = {}
62
62
  rel_joins = []
63
63
  params.each do |k, v|
64
- if (ks = k.split('.')).length > 1
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
- :has_many
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
- # Figure out if we need to specially call out the foreign key
198
- if need_fk # Funky foreign key?
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
- x = _brick_establish_connection(*args)
294
+ conn = _brick_establish_connection(*args)
295
+ _brick_reflect_tables
296
+ conn
297
+ end
277
298
 
278
- if (relations = ::Brick.relations).empty?
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
- result = ActiveRecord::Base.connection.execute(sql)
393
- result = result.values unless result.is_a?(Array)
394
- result.each { |fk| ::Brick._add_bt_and_hm(fk, relations) }
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
- # After we're initialized and before running the rest of stuff, put our configuration in place
29
- ActiveSupport.on_load(:after_initialize) do |xyz|
30
- puts "AFTER - engine initialisation"
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)
50
- end
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
- 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_model.reflect_on_all_associations.each_with_object([{}, {}]) do |a, s|
65
- case a.macro
66
- when :belongs_to
67
- # Build #brick_descrip if needed
68
- unless a.klass.instance_methods(false).include?(:brick_descrip)
69
- descrip_col = (a.klass.columns.map(&:name) - a.klass._brick_get_fks -
70
- (::Brick.config.metadata_columns || []) -
71
- [a.klass.primary_key]).first&.to_sym
72
- if descrip_col
73
- a.klass.define_method :brick_descrip do
74
- send(descrip_col)
75
- end
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
- hms_headers = hms.each_with_object(+'') { |hm, s| s << "<th>HM#{'T' if hm.last.options[:through]} #{hm.first}</th>\n" }
90
- hms_columns = hms.each_with_object(+'') do |hm, s|
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
- end
80
+ end
101
81
 
102
- inline = case args.first
103
- when 'index'
104
- "<p style=\"color: green\"><%= notice %></p>
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
- when 'show'
165
- "<%= @#{@_brick_model.name.underscore}.inspect %>"
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
- if ::Brick.enable_routes?
179
- ActionDispatch::Routing::RouteSet.class_exec do
180
- alias _brick_finalize_routeset! finalize!
181
- def finalize!(*args, **options)
182
- unless @finalized
183
- existing_controllers = routes.each_with_object({}) { |r, s| c = r.defaults[:controller]; s[c] = nil if c }
184
- ::Rails.application.routes.append do
185
- # %%% TODO: If no auto-controllers then enumerate the controllers folder in order to build matching routes
186
- # If auto-controllers and auto-models are both enabled then this makes sense:
187
- relations = (::Brick.instance_variable_get(:@relations) || {})[ActiveRecord::Base.connection_pool.object_id] || {}
188
- relations.each do |k, v|
189
- unless existing_controllers.key?(controller_name = k.underscore.pluralize)
190
- options = {}
191
- options[:only] = [:index, :show] if v.key?(:isView)
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
- # Additional references (virtual foreign keys)
203
- if (ars = ::Brick.config.additional_references)
204
- ars = ars.call if ars.is_a?(Proc)
205
- ars = ars.to_a unless ars.is_a?(Array)
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
- # Find associative tables that can be set up for has_many :through
213
- ::Brick.relations.each do |_key, tbl|
214
- tbl_cols = tbl[:cols].keys
215
- fks = tbl[:fks].each_with_object({}) { |fk, s| s[fk.last[:fk]] = fk.last[:inverse_table] if fk.last[:is_bt]; s }
216
- # Aside from the primary key and the metadata columns created_at, updated_at, and deleted_at, if this table only has
217
- # foreign keys then it can act as an associative table and thus be used with has_many :through.
218
- if fks.length > 1 && (tbl_cols - fks.keys - (::Brick.config.metadata_columns || []) - tbl[:pkey].values.first).length.zero?
219
- fks.each { |fk| tbl[:hmt_fks][fk.first] = fk.last }
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
@@ -5,7 +5,7 @@ module Brick
5
5
  module VERSION
6
6
  MAJOR = 1
7
7
  MINOR = 0
8
- TINY = 4
8
+ TINY = 5
9
9
 
10
10
  # PRE is nil unless it's a pre-release (beta, RC, etc.)
11
11
  PRE = nil
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=(value)
163
- Brick.config.additional_references = value
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
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-16 00:00:00.000000000 Z
11
+ date: 2022-03-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord