brick 1.0.1 → 1.0.2
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 +26 -2
- data/lib/brick/extensions.rb +40 -21
- data/lib/brick/frameworks/rails/engine.rb +141 -4
- data/lib/brick/version_number.rb +1 -1
- data/lib/brick.rb +15 -11
- data/lib/generators/brick/install_generator.rb +112 -66
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 36447b749972f091f6d4c7c9127a7abfd5291d159f4ab81e0fb423feae7c2c03
|
4
|
+
data.tar.gz: eb2d1c36e67dd692ac765198c132c801c8633e32ecd199f42605f7659e7f3abd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: da45315cae612125917448549f3be6cf163c6dc30ac97794f57544321b2c21536600903e9eb30a379fc6a0845656fe7704df863db13ad62a70c623f4f9cba454
|
7
|
+
data.tar.gz: 64ec86f256752004d07447e94788e453f3e6cf9006082629f5e46791b36d6ce8031e22753217d5f23be5b672f65b35ddb9a55b696db5de0bb85686f854154fee
|
data/lib/brick/config.rb
CHANGED
@@ -57,12 +57,36 @@ module Brick
|
|
57
57
|
end
|
58
58
|
|
59
59
|
# Additional table associations to use (Think of these as virtual foreign keys perhaps)
|
60
|
+
def additional_references
|
61
|
+
@mutex.synchronize { @additional_references }
|
62
|
+
end
|
63
|
+
|
60
64
|
def additional_references=(references)
|
61
65
|
@mutex.synchronize { @additional_references = references }
|
62
66
|
end
|
63
67
|
|
64
|
-
def
|
65
|
-
@mutex.synchronize { @
|
68
|
+
def skip_database_views
|
69
|
+
@mutex.synchronize { @skip_database_views }
|
70
|
+
end
|
71
|
+
|
72
|
+
def skip_database_views=(disable)
|
73
|
+
@mutex.synchronize { @skip_database_views = disable }
|
74
|
+
end
|
75
|
+
|
76
|
+
def exclude_tables
|
77
|
+
@mutex.synchronize { @exclude_tables }
|
78
|
+
end
|
79
|
+
|
80
|
+
def exclude_tables=(value)
|
81
|
+
@mutex.synchronize { @exclude_tables = value }
|
82
|
+
end
|
83
|
+
|
84
|
+
def metadata_columns
|
85
|
+
@mutex.synchronize { @metadata_columns }
|
86
|
+
end
|
87
|
+
|
88
|
+
def metadata_columns=(columns)
|
89
|
+
@mutex.synchronize { @metadata_columns = columns }
|
66
90
|
end
|
67
91
|
end
|
68
92
|
end
|
data/lib/brick/extensions.rb
CHANGED
@@ -33,9 +33,38 @@
|
|
33
33
|
# ==========================================================
|
34
34
|
|
35
35
|
# By default all models indicate that they are not views
|
36
|
-
|
37
|
-
|
38
|
-
|
36
|
+
module ActiveRecord
|
37
|
+
class Base
|
38
|
+
def self.is_view?
|
39
|
+
false
|
40
|
+
end
|
41
|
+
|
42
|
+
# Used to show a little prettier name for an object
|
43
|
+
def brick_descrip
|
44
|
+
klass = self.class
|
45
|
+
klass.primary_key ? "#{klass.name} ##{send(klass.primary_key)}" : to_s
|
46
|
+
end
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
def self._brick_get_fks
|
51
|
+
@_brick_get_fks ||= reflect_on_all_associations.select { |a2| a2.macro == :belongs_to }.map(&:foreign_key)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
class Relation
|
56
|
+
def brick_where(params)
|
57
|
+
wheres = {}
|
58
|
+
params.each do |k, v|
|
59
|
+
next unless klass._brick_get_fks.include?(k)
|
60
|
+
|
61
|
+
wheres[k] = v.split(',')
|
62
|
+
end
|
63
|
+
unless wheres.empty?
|
64
|
+
where!(wheres)
|
65
|
+
wheres # Return the specific parameters that we did use
|
66
|
+
end
|
67
|
+
end
|
39
68
|
end
|
40
69
|
end
|
41
70
|
|
@@ -88,6 +117,9 @@ class Object
|
|
88
117
|
private
|
89
118
|
|
90
119
|
def build_model(model_name, singular_table_name, table_name, relations, matching)
|
120
|
+
return if ((is_view = (relation = relations[matching]).key?(:isView)) && ::Brick.config.skip_database_views) ||
|
121
|
+
::Brick.config.exclude_tables.include?(matching)
|
122
|
+
|
91
123
|
# Are they trying to use a pluralised class name such as "Employees" instead of "Employee"?
|
92
124
|
if table_name == singular_table_name && !ActiveSupport::Inflector.inflections.uncountable.include?(table_name)
|
93
125
|
raise NameError.new("Class name for a model that references table \"#{matching}\" should be \"#{ActiveSupport::Inflector.singularize(model_name)}\".")
|
@@ -100,7 +132,7 @@ class Object
|
|
100
132
|
|
101
133
|
# Override models backed by a view so they return true for #is_view?
|
102
134
|
# (Dynamically-created controllers and view templates for such models will then act in a read-only way)
|
103
|
-
if
|
135
|
+
if is_view
|
104
136
|
new_model_class.define_singleton_method :'is_view?' do
|
105
137
|
true
|
106
138
|
end
|
@@ -183,7 +215,6 @@ class Object
|
|
183
215
|
[built_model, code]
|
184
216
|
end
|
185
217
|
|
186
|
-
|
187
218
|
def build_controller(class_name, plural_class_name, model, relations)
|
188
219
|
table_name = ActiveSupport::Inflector.underscore(plural_class_name)
|
189
220
|
singular_table_name = ActiveSupport::Inflector.singularize(table_name)
|
@@ -194,9 +225,11 @@ class Object
|
|
194
225
|
|
195
226
|
code << " def index\n"
|
196
227
|
code << " @#{table_name} = #{model.name}#{model.primary_key ? ".order(#{model.primary_key.inspect}" : '.all'})\n"
|
228
|
+
code << " @#{table_name}.brick_where(params)\n"
|
197
229
|
code << " end\n"
|
198
230
|
self.define_method :index do
|
199
231
|
ar_relation = model.primary_key ? model.order(model.primary_key) : model.all
|
232
|
+
instance_variable_set(:@_brick_params, ar_relation.brick_where(params))
|
200
233
|
instance_variable_set("@#{table_name}".to_sym, ar_relation)
|
201
234
|
end
|
202
235
|
|
@@ -234,10 +267,9 @@ end
|
|
234
267
|
# ==========================================================
|
235
268
|
|
236
269
|
module ActiveRecord::ConnectionHandling
|
237
|
-
alias
|
270
|
+
alias _brick_establish_connection establish_connection
|
238
271
|
def establish_connection(*args)
|
239
|
-
|
240
|
-
x = old_establish_connection(*args)
|
272
|
+
x = _brick_establish_connection(*args)
|
241
273
|
|
242
274
|
if (relations = ::Brick.relations).empty?
|
243
275
|
schema = 'public'
|
@@ -268,9 +300,6 @@ module ActiveRecord::ConnectionHandling
|
|
268
300
|
# next if internal_views.include?(r['relation_name']) # Skip internal views such as v_all_assessments
|
269
301
|
|
270
302
|
relation = relations[r['relation_name']]
|
271
|
-
relation[:index] = r['relation_name'].underscore
|
272
|
-
relation[:show] = relation[:index].singularize
|
273
|
-
relation[:index] = relation[:index].pluralize
|
274
303
|
relation[:isView] = true if r['table_type'] == 'VIEW'
|
275
304
|
col_name = r['column_name']
|
276
305
|
cols = relation[:cols] # relation.fetch(:cols) { relation[:cols] = [] }
|
@@ -303,16 +332,6 @@ module ActiveRecord::ConnectionHandling
|
|
303
332
|
# AND kcu2.TABLE_NAME = ?;", Apartment::Tenant.current, table_name
|
304
333
|
])
|
305
334
|
ActiveRecord::Base.connection.execute(sql).values.each { |fk| ::Brick._add_bt_and_hm(fk, relations) }
|
306
|
-
|
307
|
-
# Find associative tables that can be set up for has_many :through
|
308
|
-
relations.each do |_key, tbl|
|
309
|
-
tbl_cols = tbl[:cols].keys
|
310
|
-
fks = tbl[:fks].each_with_object({}) { |fk, s| s[fk.last[:fk]] = fk.last[:inverse_table] if fk.last[:is_bt]; s }
|
311
|
-
# Aside from the primary key and created_at, updated_at,This table has only foreign keys?
|
312
|
-
if fks.length > 1 && (tbl_cols - fks.keys - ['created_at', 'updated_at', 'deleted_at', 'last_update'] - tbl[:pkey].values.first).length.zero?
|
313
|
-
fks.each { |fk| tbl[:hmt_fks][fk.first] = fk.last }
|
314
|
-
end
|
315
|
-
end
|
316
335
|
end
|
317
336
|
|
318
337
|
puts "Classes built from tables:"
|
@@ -37,13 +37,110 @@ module Brick
|
|
37
37
|
alias :_brick_find_template :find_template
|
38
38
|
def find_template(*args, **options)
|
39
39
|
if @_brick_model
|
40
|
+
model_name = @_brick_model.name
|
41
|
+
pk = @_brick_model.primary_key
|
42
|
+
obj_name = model_name.underscore
|
43
|
+
table_name = model_name.pluralize.underscore
|
44
|
+
# This gets has_many as well as has_many :through
|
45
|
+
# %%% weed out ones that don't have an available model to reference
|
46
|
+
bts, hms = @_brick_model.reflect_on_all_associations.each_with_object([{}, {}]) do |a, s|
|
47
|
+
case a.macro
|
48
|
+
when :belongs_to
|
49
|
+
# Build #brick_descrip if needed
|
50
|
+
unless a.klass.instance_methods(false).include?(:brick_descrip)
|
51
|
+
descrip_col = (a.klass.columns.map(&:name) - a.klass._brick_get_fks -
|
52
|
+
(::Brick.config.metadata_columns || []) -
|
53
|
+
[a.klass.primary_key]).first&.to_sym
|
54
|
+
if descrip_col
|
55
|
+
a.klass.define_method :brick_descrip do
|
56
|
+
send(descrip_col)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
s.first[a.foreign_key] = [a.name, a.klass]
|
62
|
+
when :has_many
|
63
|
+
s.last[a.name] = a
|
64
|
+
end
|
65
|
+
s
|
66
|
+
end
|
67
|
+
# Weed out has_manys that go to an associative table
|
68
|
+
hms.select { |k, v| v.options[:through] }.each { |_k, hmt| hms.delete(hmt.options[:through]) }
|
69
|
+
show_obj_blurb = "<td><%= link_to \"#\{#{obj_name}.class.name\} ##\{#{obj_name}.id\}\", #{obj_name} %></td>\n"
|
70
|
+
hms_headers = hms.each_with_object(+'') { |hm, s| s << "<th>HM #{hm.first}</th>\n" }
|
71
|
+
hms_columns = hms.each_with_object(+'') do |hm, s|
|
72
|
+
s << "<td>
|
73
|
+
<%= link_to \"#\{#{obj_name}.#{hm.first}.count\} #{hm.first}\", #{hm.last.klass.name.underscore.pluralize}_path({ #{hm.last.foreign_key}: #{obj_name}.#{pk} }) %>
|
74
|
+
</td>\n"
|
75
|
+
end
|
76
|
+
|
40
77
|
inline = case args.first
|
41
78
|
when 'index'
|
42
|
-
|
43
|
-
|
79
|
+
"<p style=\"color: green\"><%= notice %></p>
|
80
|
+
|
81
|
+
<h1>#{model_name.pluralize}</h1>
|
82
|
+
<% if @_brick_params&.present? %><h3>where <%= @_brick_params.each_with_object([]) { |v, s| s << \"#\{v.first\} = #\{v.last.inspect\}\" }.join(', ') %></h3><% end %>
|
83
|
+
|
84
|
+
<table id=\"#{table_name}\">
|
85
|
+
<tr>
|
86
|
+
<% is_first = true; is_need_id_col = nil
|
87
|
+
bts = { #{bts.each_with_object([]) { |v, s| s << "#{v.first.inspect} => [#{v.last.first.inspect}, #{v.last.last.name}, #{v.last.last.primary_key.inspect}]"}.join(', ')} }
|
88
|
+
@#{table_name}.columns.map(&:name).each do |col| %>
|
89
|
+
<% next if col == '#{pk}' || ::Brick.config.metadata_columns.include?(col) %>
|
90
|
+
<th>
|
91
|
+
<% if bt = bts[col]
|
92
|
+
if is_first
|
93
|
+
is_first = false
|
94
|
+
is_need_id_col = true %>
|
95
|
+
</th><th>
|
96
|
+
<% end %>
|
97
|
+
BT <%= bt[1].name %>
|
98
|
+
<% else
|
99
|
+
is_first = false %>
|
100
|
+
<%= col %>
|
101
|
+
<% end %>
|
102
|
+
</th>
|
103
|
+
<% end %>
|
104
|
+
<% if is_first # STILL haven't been able to write a first non-key / non-metadata column?
|
105
|
+
is_first = false
|
106
|
+
is_need_id_col = true %>
|
107
|
+
<td></td>
|
108
|
+
<% end %>
|
109
|
+
#{hms_headers}
|
110
|
+
</tr>
|
111
|
+
|
112
|
+
<% @#{table_name}.each do |#{obj_name}| %>
|
113
|
+
<tr>
|
114
|
+
<% if is_need_id_col %>
|
115
|
+
<td>#{show_obj_blurb}</td>
|
116
|
+
<% end %>
|
117
|
+
<% is_first = true; #{obj_name}.attributes.each do |k, val| %>
|
118
|
+
<% next if k == '#{pk}' || ::Brick.config.metadata_columns.include?(k) %>
|
119
|
+
<% if (bt = bts[k]) %>
|
120
|
+
<td>
|
121
|
+
<%= obj = bt[1].find_by(bt.last => val); link_to obj.brick_descrip, obj %>
|
122
|
+
<% elsif is_first %>
|
123
|
+
<td>
|
124
|
+
<%= is_first = false; link_to val, #{obj_name} %>
|
125
|
+
<% else %>
|
126
|
+
<td>
|
127
|
+
<%= val %>
|
128
|
+
<% end %>
|
129
|
+
</td>
|
130
|
+
<% end %>
|
131
|
+
#{hms_columns}
|
132
|
+
<!-- td>X</td -->
|
133
|
+
</tr>
|
134
|
+
<% end %>
|
135
|
+
</table>
|
136
|
+
|
137
|
+
<%= link_to \"New #{obj_name}\", new_#{obj_name}_path %>
|
138
|
+
"
|
139
|
+
# "<%= @#{@_brick_model.name.underscore.pluralize}.inspect %>"
|
44
140
|
when 'show'
|
45
141
|
"<%= @#{@_brick_model.name.underscore}.inspect %>"
|
46
142
|
end
|
143
|
+
puts inline
|
47
144
|
# As if it were an inline template (see #determine_template in actionview-5.2.6.2/lib/action_view/renderer/template_renderer.rb)
|
48
145
|
keys = options.has_key?(:locals) ? options[:locals].keys : []
|
49
146
|
handler = ActionView::Template.handler_for_extension(options[:type] || 'erb')
|
@@ -55,10 +152,39 @@ module Brick
|
|
55
152
|
end
|
56
153
|
end
|
57
154
|
|
58
|
-
# Auto-routing behaviour
|
59
155
|
if (::Brick.enable_routes = app.config.brick.fetch(:enable_routes, true))
|
60
|
-
::
|
156
|
+
ActionDispatch::Routing::RouteSet.class_exec do
|
157
|
+
alias _brick_finalize_routeset! finalize!
|
158
|
+
def finalize!(*args, **options)
|
159
|
+
unless @finalized
|
160
|
+
existing_controllers = routes.each_with_object({}) { |r, s| c = r.defaults[:controller]; s[c] = nil if c }
|
161
|
+
::Rails.application.routes.append do
|
162
|
+
# %%% TODO: If no auto-controllers then enumerate the controllers folder in order to build matching routes
|
163
|
+
# If auto-controllers and auto-models are both enabled then this makes sense:
|
164
|
+
relations = (::Brick.instance_variable_get(:@relations) || {})[ActiveRecord::Base.connection_pool.object_id] || {}
|
165
|
+
relations.each do |k, v|
|
166
|
+
unless existing_controllers.key?(controller_name = k.underscore.pluralize)
|
167
|
+
options = {}
|
168
|
+
options[:only] = [:index, :show] if v.key?(:isView)
|
169
|
+
send(:resources, controller_name.to_sym, **options)
|
170
|
+
end
|
171
|
+
end
|
172
|
+
end
|
173
|
+
end
|
174
|
+
_brick_finalize_routeset!(*args, **options)
|
175
|
+
end
|
176
|
+
end
|
61
177
|
end
|
178
|
+
|
179
|
+
# Do not consider database views when auto-creating models
|
180
|
+
::Brick.skip_database_views = app.config.brick.fetch(:skip_database_views, false)
|
181
|
+
|
182
|
+
# Specific database tables and views to omit when auto-creating models
|
183
|
+
::Brick.exclude_tables = app.config.brick.fetch(:exclude_tables, [])
|
184
|
+
|
185
|
+
# Columns to treat as being metadata for purposes of identifying associative tables for has_many :through
|
186
|
+
::Brick.metadata_columns = app.config.brick.fetch(:metadata_columns, ['created_at', 'updated_at', 'deleted_at'])
|
187
|
+
|
62
188
|
# Additional references (virtual foreign keys)
|
63
189
|
if (ars = (::Brick.additional_references = app.config.brick.fetch(:additional_references, nil)))
|
64
190
|
ars = ars.call if ars.is_a?(Proc)
|
@@ -68,6 +194,17 @@ module Brick
|
|
68
194
|
::Brick._add_bt_and_hm(fk[0..2])
|
69
195
|
end
|
70
196
|
end
|
197
|
+
|
198
|
+
# Find associative tables that can be set up for has_many :through
|
199
|
+
::Brick.relations.each do |_key, tbl|
|
200
|
+
tbl_cols = tbl[:cols].keys
|
201
|
+
fks = tbl[:fks].each_with_object({}) { |fk, s| s[fk.last[:fk]] = fk.last[:inverse_table] if fk.last[:is_bt]; s }
|
202
|
+
# Aside from the primary key and the metadata columns created_at, updated_at, and deleted_at, if this table only has
|
203
|
+
# foreign keys then it can act as an associative table and thus be used with has_many :through.
|
204
|
+
if fks.length > 1 && (tbl_cols - fks.keys - (::Brick.config.metadata_columns || []) - tbl[:pkey].values.first).length.zero?
|
205
|
+
fks.each { |fk| tbl[:hmt_fks][fk.first] = fk.last }
|
206
|
+
end
|
207
|
+
end
|
71
208
|
end
|
72
209
|
end
|
73
210
|
end
|
data/lib/brick/version_number.rb
CHANGED
data/lib/brick.rb
CHANGED
@@ -79,17 +79,6 @@ require 'brick/config'
|
|
79
79
|
require 'brick/frameworks/rails'
|
80
80
|
module Brick
|
81
81
|
class << self
|
82
|
-
def append_routes
|
83
|
-
::Rails.application.routes.append do
|
84
|
-
relations = (::Brick.instance_variable_get(:@relations) || {})[ActiveRecord::Base.connection_pool.object_id] || {}
|
85
|
-
relations.each do |k, v|
|
86
|
-
options = {}
|
87
|
-
options[:only] = [:index, :show] if v.key?(:isView)
|
88
|
-
send(:resources, k.underscore.pluralize.to_sym, **options)
|
89
|
-
end
|
90
|
-
end
|
91
|
-
end
|
92
|
-
|
93
82
|
# All tables and views (what Postgres calls "relations" including column and foreign key info)
|
94
83
|
def relations
|
95
84
|
connections = Brick.instance_variable_get(:@relations) ||
|
@@ -150,6 +139,21 @@ module Brick
|
|
150
139
|
!!Brick.config.enable_routes
|
151
140
|
end
|
152
141
|
|
142
|
+
# @api public
|
143
|
+
def skip_database_views=(value)
|
144
|
+
Brick.config.skip_database_views = value
|
145
|
+
end
|
146
|
+
|
147
|
+
# @api public
|
148
|
+
def exclude_tables=(value)
|
149
|
+
Brick.config.exclude_tables = value
|
150
|
+
end
|
151
|
+
|
152
|
+
# @api public
|
153
|
+
def metadata_columns=(value)
|
154
|
+
Brick.config.metadata_columns = value
|
155
|
+
end
|
156
|
+
|
153
157
|
# Additional table associations to use (Think of these as virtual foreign keys perhaps)
|
154
158
|
# @api public
|
155
159
|
def additional_references=(value)
|
@@ -1,12 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'rails/generators'
|
4
|
-
require 'rails/generators/active_record'
|
4
|
+
# require 'rails/generators/active_record'
|
5
5
|
|
6
6
|
module Brick
|
7
|
-
# Auto-generates an IMPORT_TEMPLATE entry for one or more models
|
8
7
|
class InstallGenerator < ::Rails::Generators::Base
|
9
|
-
include ::Rails::Generators::Migration
|
8
|
+
# include ::Rails::Generators::Migration
|
10
9
|
|
11
10
|
source_root File.expand_path('templates', __dir__)
|
12
11
|
class_option(
|
@@ -16,81 +15,128 @@ module Brick
|
|
16
15
|
desc: 'Store changeset (diff) with each version'
|
17
16
|
)
|
18
17
|
|
19
|
-
desc 'Generates
|
20
|
-
' Also generates an initializer file for configuring Brick'
|
18
|
+
desc 'Generates an initializer file for configuring Brick'
|
21
19
|
|
22
|
-
def
|
23
|
-
|
24
|
-
|
25
|
-
end
|
20
|
+
def create_initializer_file
|
21
|
+
unless File.exists?(filename = 'config/initializers/brick.rb')
|
22
|
+
create_file filename, "# frozen_string_literal: true
|
26
23
|
|
27
|
-
|
28
|
-
|
29
|
-
end
|
24
|
+
# # Settings for the Brick gem
|
25
|
+
# # (By default this auto-creates models, controllers, views, and routes on-the-fly.)
|
30
26
|
|
31
|
-
|
27
|
+
# # Normally these all start out as being enabled, but can be selectively disabled:
|
28
|
+
# Brick.enable_routes = false
|
29
|
+
# Brick.enable_models = false
|
30
|
+
# Brick.enable_controllers = false
|
31
|
+
# Brick.enable_views = false
|
32
|
+
|
33
|
+
# # By default models are auto-created from database views, and set to be read-only. This can be skipped.
|
34
|
+
# Brick.skip_database_views = true
|
35
|
+
|
36
|
+
# # Any tables or views you'd like to skip when auto-creating models
|
37
|
+
# Brick.exclude_tables = ['custom_metadata', 'version_info']
|
32
38
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
39
|
+
# # Additional table references which are used to create has_many / belongs_to associations inside auto-created
|
40
|
+
# # models. (You can consider these to be \"virtual foreign keys\" if you wish)... You only have to add these
|
41
|
+
# # in cases where your database for some reason does not have foreign key constraints defined. Sometimes for
|
42
|
+
# # performance reasons or just out of sheer laziness these might be missing.
|
43
|
+
# # Each of these virtual foreign keys is defined as an array having three values:
|
44
|
+
# # foreign table name / foreign key column / primary table name.
|
45
|
+
# # (We boldly expect that the primary key identified by ActiveRecord on the primary table will be accurate,
|
46
|
+
# # usually this is \"id\" but there are some good smarts that are used in case some other column has been set
|
47
|
+
# # to be the primary key.
|
48
|
+
# Brick.additional_references = [['orders', 'customer_id', 'customer'],
|
49
|
+
# ['customer', 'region_id', 'regions']]
|
50
|
+
|
51
|
+
# # We normally don't consider the timestamp columns \"created_at\", \"updated_at\", and \"deleted_at\" to count when
|
52
|
+
# # finding tables which can serve as associative tables in an N:M association. That is, ones that can be a
|
53
|
+
# # part of a has_many :through association. If you want to use different exclusion columns than our defaults
|
54
|
+
# # then this setting resets that list. For instance, here is the override for the Sakila sample database:
|
55
|
+
# Brick.metadata_columns = ['last_updated']
|
56
|
+
|
57
|
+
# # If a default route is not supplied, Brick attempts to find the most \"central\" table and wires up the default
|
58
|
+
# # route to go to the :index action for what would be a controller for that table. You can specify any controller
|
59
|
+
# # name and action you wish in order to override this and have that be the default route when none other has been
|
60
|
+
# # specified in routes.rb or elsewhere. (Or just use an empty string in order to disable this behaviour.)
|
61
|
+
# Brick.default_route_fallback = 'customers' # This defaults to \"customers/index\"
|
62
|
+
# Brick.default_route_fallback = 'orders/outstanding' # Example of a non-RESTful route
|
63
|
+
# Brick.default_route_fallback = '' # Omits setting a default route in the absence of any other
|
64
|
+
"
|
45
65
|
end
|
46
66
|
end
|
47
67
|
|
68
|
+
# def create_migration_file
|
69
|
+
# add_brick_migration('create_versions')
|
70
|
+
# add_brick_migration('add_object_changes_to_versions') if options.with_changes?
|
71
|
+
# end
|
72
|
+
|
73
|
+
# def self.next_migration_number(dirname)
|
74
|
+
# ::ActiveRecord::Generators::Base.next_migration_number(dirname)
|
75
|
+
# end
|
76
|
+
|
77
|
+
protected
|
78
|
+
|
79
|
+
# def add_brick_migration(template)
|
80
|
+
# migration_dir = File.expand_path('db/migrate')
|
81
|
+
# if self.class.migration_exists?(migration_dir, template)
|
82
|
+
# ::Kernel.warn "Migration already exists: #{template}"
|
83
|
+
# else
|
84
|
+
# migration_template(
|
85
|
+
# "#{template}.rb.erb",
|
86
|
+
# "db/migrate/#{template}.rb",
|
87
|
+
# item_type_options: item_type_options,
|
88
|
+
# migration_version: migration_version,
|
89
|
+
# versions_table_options: versions_table_options
|
90
|
+
# )
|
91
|
+
# end
|
92
|
+
# end
|
93
|
+
|
48
94
|
private
|
49
95
|
|
50
|
-
# MySQL 5.6 utf8mb4 limit is 191 chars for keys used in indexes.
|
51
|
-
def item_type_options
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
end
|
96
|
+
# # MySQL 5.6 utf8mb4 limit is 191 chars for keys used in indexes.
|
97
|
+
# def item_type_options
|
98
|
+
# opt = { null: false }
|
99
|
+
# opt[:limit] = 191 if mysql?
|
100
|
+
# ", #{opt}"
|
101
|
+
# end
|
56
102
|
|
57
|
-
def migration_version
|
58
|
-
|
103
|
+
# def migration_version
|
104
|
+
# return unless (major = ActiveRecord::VERSION::MAJOR) >= 5
|
59
105
|
|
60
|
-
|
61
|
-
end
|
106
|
+
# "[#{major}.#{ActiveRecord::VERSION::MINOR}]"
|
107
|
+
# end
|
62
108
|
|
63
|
-
# Class names of MySQL adapters.
|
64
|
-
# - `MysqlAdapter` - Used by gems: `mysql`, `activerecord-jdbcmysql-adapter`.
|
65
|
-
# - `Mysql2Adapter` - Used by `mysql2` gem.
|
66
|
-
def mysql?
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
end
|
109
|
+
# # Class names of MySQL adapters.
|
110
|
+
# # - `MysqlAdapter` - Used by gems: `mysql`, `activerecord-jdbcmysql-adapter`.
|
111
|
+
# # - `Mysql2Adapter` - Used by `mysql2` gem.
|
112
|
+
# def mysql?
|
113
|
+
# [
|
114
|
+
# 'ActiveRecord::ConnectionAdapters::MysqlAdapter',
|
115
|
+
# 'ActiveRecord::ConnectionAdapters::Mysql2Adapter'
|
116
|
+
# ].freeze.include?(ActiveRecord::Base.connection.class.name)
|
117
|
+
# end
|
72
118
|
|
73
|
-
# Even modern versions of MySQL still use `latin1` as the default character
|
74
|
-
# encoding. Many users are not aware of this, and run into trouble when they
|
75
|
-
# try to use Brick in apps that otherwise tend to use UTF-8. Postgres, by
|
76
|
-
# comparison, uses UTF-8 except in the unusual case where the OS is configured
|
77
|
-
# with a custom locale.
|
78
|
-
#
|
79
|
-
# - https://dev.mysql.com/doc/refman/5.7/en/charset-applications.html
|
80
|
-
# - http://www.postgresql.org/docs/9.4/static/multibyte.html
|
81
|
-
#
|
82
|
-
# Furthermore, MySQL's original implementation of UTF-8 was flawed, and had
|
83
|
-
# to be fixed later by introducing a new charset, `utf8mb4`.
|
84
|
-
#
|
85
|
-
# - https://mathiasbynens.be/notes/mysql-utf8mb4
|
86
|
-
# - https://dev.mysql.com/doc/refman/5.5/en/charset-unicode-utf8mb4.html
|
87
|
-
#
|
88
|
-
def versions_table_options
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
end
|
119
|
+
# # Even modern versions of MySQL still use `latin1` as the default character
|
120
|
+
# # encoding. Many users are not aware of this, and run into trouble when they
|
121
|
+
# # try to use Brick in apps that otherwise tend to use UTF-8. Postgres, by
|
122
|
+
# # comparison, uses UTF-8 except in the unusual case where the OS is configured
|
123
|
+
# # with a custom locale.
|
124
|
+
# #
|
125
|
+
# # - https://dev.mysql.com/doc/refman/5.7/en/charset-applications.html
|
126
|
+
# # - http://www.postgresql.org/docs/9.4/static/multibyte.html
|
127
|
+
# #
|
128
|
+
# # Furthermore, MySQL's original implementation of UTF-8 was flawed, and had
|
129
|
+
# # to be fixed later by introducing a new charset, `utf8mb4`.
|
130
|
+
# #
|
131
|
+
# # - https://mathiasbynens.be/notes/mysql-utf8mb4
|
132
|
+
# # - https://dev.mysql.com/doc/refman/5.5/en/charset-unicode-utf8mb4.html
|
133
|
+
# #
|
134
|
+
# def versions_table_options
|
135
|
+
# if mysql?
|
136
|
+
# ', { options: "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci" }'
|
137
|
+
# else
|
138
|
+
# ''
|
139
|
+
# end
|
140
|
+
# end
|
95
141
|
end
|
96
142
|
end
|