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 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