brick 1.0.1 → 1.0.2
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 +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
|