rails_com 1.2.0 → 1.2.1
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/README.md +6 -4
- data/app/assets/javascripts/rails_com/checkbox.js +59 -0
- data/app/assets/javascripts/rails_com/common.js +5 -2
- data/app/assets/javascripts/rails_com/fetch_xhr_script.js +3 -37
- data/app/assets/javascripts/rails_com/sidebar.js +40 -0
- data/app/controllers/common_controller.rb +0 -8
- data/app/controllers/concerns/the_common_api.rb +2 -2
- data/app/helpers/rails_com/active_helper.rb +1 -0
- data/app/helpers/{rails_com_helper.rb → rails_com/assets_helper.rb} +2 -10
- data/app/helpers/rails_com/common_helper.rb +13 -0
- data/app/helpers/rails_com/time_helper.rb +22 -0
- data/app/models/state_machine.rb +63 -15
- data/app/views/shared/_locales.html.erb +1 -1
- data/config/locales/en.yml +7 -1
- data/config/locales/zh.datetime.yml +44 -0
- data/config/locales/zh.yml +9 -0
- data/config/routes.rb +0 -4
- data/lib/mina/puma.rb +3 -2
- data/lib/mina/whenever.rb +27 -0
- data/lib/rails_com/config.rb +11 -0
- data/lib/rails_com/core_ext/array.rb +54 -0
- data/lib/rails_com/model_helper.rb +55 -4
- data/lib/rails_com/rails_ext/activestorage_attached.rb +32 -0
- data/lib/rails_com/rails_ext/persistence_sneakily.rb +11 -0
- data/lib/rails_com/rails_ext/scaffold_generator.rb +1 -0
- data/lib/rails_com/rails_ext/template_renderer.rb +3 -3
- data/lib/rails_com/rails_ext/translation_helper.rb +18 -0
- data/lib/rails_com/routes.rb +5 -0
- data/lib/rails_com/setting.rb +34 -0
- data/lib/rails_com/version.rb +1 -1
- data/lib/rails_com.rb +7 -5
- data/lib/templates/erb/scaffold/_search_form.html.erb.tt +1 -1
- data/lib/templates/erb/scaffold/edit.html.erb.tt +7 -12
- data/lib/templates/erb/scaffold/index.html.erb.tt +32 -36
- data/lib/templates/erb/scaffold/new.html.erb.tt +8 -12
- data/lib/utils/ip_helper.rb +21 -0
- data/lib/utils/time_helper.rb +37 -0
- metadata +17 -12
- data/config/initializers/time_format.rb +0 -1
- data/lib/assets/javascripts/semantic.js +0 -11
- data/lib/nondigest_assets/fonts/themes/default/assets/fonts/icons.eot +0 -0
- data/lib/nondigest_assets/fonts/themes/default/assets/fonts/icons.otf +0 -0
- data/lib/nondigest_assets/fonts/themes/default/assets/fonts/icons.svg +0 -947
- data/lib/nondigest_assets/fonts/themes/default/assets/fonts/icons.ttf +0 -0
- data/lib/nondigest_assets/fonts/themes/default/assets/fonts/icons.woff +0 -0
- data/lib/nondigest_assets/fonts/themes/default/assets/fonts/icons.woff2 +0 -0
- data/lib/nondigest_assets/fonts/themes/default/assets/images/flags.png +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2ffa9f1ff257d36fdc9bb11415039affae4ee7a1589f7c15f565e911ca6fe33a
|
4
|
+
data.tar.gz: 36054a13e2f3a8b7ea8c8130dcb16185612bc8b575c701eaaf0630b6c8f0ce0c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 27c0ff46020d0a06076a4c085deea1ce604434b97836232c3ccea537b05b20c7be7960cf2dad3786dfa365f1a85994e7f4b8bc68e9a759c7dd8e598a98e31f95
|
7
|
+
data.tar.gz: 0d745dbbe1560f2ccfb5fe2a6172ef3180903bec46aa8f40b59d864bb9b447ae8157719c7ed05822086c468a27e82282085e02709720357534af651c247ba130
|
data/README.md
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
# RailsCom
|
2
|
-
|
2
|
+
Rails Common engine, with many sugars!
|
3
3
|
|
4
4
|
## Installation
|
5
5
|
Add this line to your application's Gemfile:
|
@@ -17,9 +17,11 @@ Or install it yourself as:
|
|
17
17
|
```bash
|
18
18
|
$ gem install rails_com
|
19
19
|
```
|
20
|
-
##
|
21
|
-
|
22
|
-
|
20
|
+
## Features
|
21
|
+
* examples: puma, configs etc.
|
22
|
+
* rails and ruby core extension;
|
23
|
+
* methods deal rails model/controller/routes etc.
|
24
|
+
* some helpers, for generator uuid based on time and more;
|
23
25
|
|
24
26
|
### View: add link
|
25
27
|
```erb
|
@@ -0,0 +1,59 @@
|
|
1
|
+
function listenCheckedIds(name) {
|
2
|
+
var checked = 'input[name=' + name + ']';
|
3
|
+
var add_ids = [];
|
4
|
+
var remove_ids = [];
|
5
|
+
var index;
|
6
|
+
window.sessionStorage.setItem(name + '_add_ids', []);
|
7
|
+
window.sessionStorage.setItem(name + '_remove_ids', []);
|
8
|
+
|
9
|
+
$(checked).change(function(){
|
10
|
+
if (this.checked && this.checked !== this.defaultChecked) {
|
11
|
+
add_ids.push(this.value)
|
12
|
+
} else if (this.checked && this.checked === this.defaultChecked) {
|
13
|
+
index = remove_ids.indexOf(this.value);
|
14
|
+
remove_ids.splice(index, 1);
|
15
|
+
} else if (!this.checked && this.checked !== this.defaultChecked) {
|
16
|
+
remove_ids.push(this.value)
|
17
|
+
} else if (!this.checked && this.checked === this.defaultChecked) {
|
18
|
+
index = add_ids.indexOf(this.value);
|
19
|
+
add_ids.splice(index, 1);
|
20
|
+
}
|
21
|
+
window.sessionStorage.setItem(name + '_remove_ids', remove_ids);
|
22
|
+
window.sessionStorage.setItem(name + '_add_ids', add_ids);
|
23
|
+
})
|
24
|
+
}
|
25
|
+
|
26
|
+
function getAddIds(name){
|
27
|
+
add_str = window.sessionStorage.getItem(name + '_add_ids');
|
28
|
+
return add_str;
|
29
|
+
}
|
30
|
+
|
31
|
+
function getRemoveIds(name){
|
32
|
+
remove_str = window.sessionStorage.getItem(name + '_remove_ids');
|
33
|
+
return remove_str
|
34
|
+
}
|
35
|
+
|
36
|
+
function toggleAll(source, name) {
|
37
|
+
var checkboxes = document.getElementsByName(name);
|
38
|
+
var add_ids = [];
|
39
|
+
var remove_ids = [];
|
40
|
+
var index;
|
41
|
+
|
42
|
+
for(checkbox of checkboxes) {
|
43
|
+
checkbox.checked = source.checked;
|
44
|
+
if (checkbox.checked && checkbox.checked !== checkbox.defaultChecked) {
|
45
|
+
add_ids.push(checkbox.value)
|
46
|
+
} else if (checkbox.checked && checkbox.checked === checkbox.defaultChecked) {
|
47
|
+
index = remove_ids.indexOf(checkbox.value);
|
48
|
+
remove_ids.splice(index, 1);
|
49
|
+
} else if (!checkbox.checked && checkbox.checked !== checkbox.defaultChecked) {
|
50
|
+
remove_ids.push(checkbox.value)
|
51
|
+
} else if (!checkbox.checked && checkbox.checked === checkbox.defaultChecked) {
|
52
|
+
index = add_ids.indexOf(checkbox.value);
|
53
|
+
add_ids.splice(index, 1);
|
54
|
+
}
|
55
|
+
}
|
56
|
+
|
57
|
+
window.sessionStorage.setItem(name + '_remove_ids', remove_ids);
|
58
|
+
window.sessionStorage.setItem(name + '_add_ids', add_ids);
|
59
|
+
}
|
@@ -1,7 +1,10 @@
|
|
1
1
|
function timeForLocalized(){
|
2
2
|
$('time[data-localized!="true"]').each(function(){
|
3
|
-
|
4
|
-
|
3
|
+
if (this.textContent.length > 0) {
|
4
|
+
var format = this.dataset['format'] || 'YYYY-MM-DD HH:mm:ss';
|
5
|
+
this.textContent = moment.utc(this.textContent).local().format(format);
|
6
|
+
this.dataset['localized'] = 'true'
|
7
|
+
}
|
5
8
|
})
|
6
9
|
}
|
7
10
|
|
@@ -8,46 +8,12 @@ function fetch_xhr_script(url, params){
|
|
8
8
|
};
|
9
9
|
|
10
10
|
fetch(url, params).then(function(response) {
|
11
|
-
return response.text()
|
11
|
+
return response.text();
|
12
12
|
}).then(function(text) {
|
13
13
|
var script = document.createElement('script');
|
14
14
|
script.text = text;
|
15
15
|
document.head.appendChild(script).parentNode.removeChild(script);
|
16
16
|
}).catch(function(ex) {
|
17
|
-
console.log('parsing failed', ex)
|
17
|
+
console.log('parsing failed', ex);
|
18
18
|
})
|
19
|
-
}
|
20
|
-
|
21
|
-
function listenCheckedIds(name) {
|
22
|
-
var checked = 'input[name="' + name + '"]:checked';
|
23
|
-
var unchecked = 'input[name="' + name + '"][checked!="checked"]';
|
24
|
-
|
25
|
-
window.add_ids = [];
|
26
|
-
window.remove_ids = [];
|
27
|
-
$(checked).change(function(){
|
28
|
-
if(this.checked){
|
29
|
-
var index = window.remove_ids.indexOf(this.value);
|
30
|
-
window.remove_ids.splice(index, 1);
|
31
|
-
} else {
|
32
|
-
window.remove_ids.push(this.value)
|
33
|
-
}
|
34
|
-
});
|
35
|
-
$(unchecked).change(function(){
|
36
|
-
if(this.checked){
|
37
|
-
window.add_ids.push(this.value)
|
38
|
-
} else {
|
39
|
-
var index = window.add_ids.indexOf(this.value);
|
40
|
-
window.add_ids.splice(index, 1);
|
41
|
-
}
|
42
|
-
});
|
43
|
-
}
|
44
|
-
|
45
|
-
function getAddIds(){
|
46
|
-
add_str = window.add_ids.join(',');
|
47
|
-
return add_str;
|
48
|
-
}
|
49
|
-
|
50
|
-
function getRemoveIds(){
|
51
|
-
remove_str = window.remove_ids.join(',');
|
52
|
-
return remove_str
|
53
|
-
}
|
19
|
+
}
|
@@ -0,0 +1,40 @@
|
|
1
|
+
function sidebarSide1() {
|
2
|
+
$('.ui.side').addClass('invisible');
|
3
|
+
$('.ui.side .ui.menu').removeClass('accordion');
|
4
|
+
$('.ui.side .ui.menu').addClass('icon');
|
5
|
+
$('.ui.side .ui.menu .dropdown.icon').remove();
|
6
|
+
$('.ui.side .ui.menu .item:not(.header)').addClass('ui dropdown');
|
7
|
+
$('.ui.dropdown.item').dropdown({on: 'hover'});
|
8
|
+
$('.ui.side .ui.menu .item:not(.header)').removeClass('hidden');
|
9
|
+
}
|
10
|
+
|
11
|
+
function sidebarSide2() {
|
12
|
+
$('.ui.side').removeClass('invisible');
|
13
|
+
$('.ui.side .ui.menu').addClass('accordion');
|
14
|
+
$('.ui.side .ui.menu').removeClass('icon');
|
15
|
+
$('.ui.side .ui.menu .item:not(.header)').removeClass('ui dropdown');
|
16
|
+
$('.ui.side .ui.menu .dropdown.icon').remove();
|
17
|
+
$('.ui.side .ui.menu .title').append('<i class="dropdown icon"></i>');
|
18
|
+
$('.ui.accordion').accordion({selector: {trigger: '.title'}});
|
19
|
+
$('.ui.side .ui.menu .item:not(.header)').dropdown('destroy');
|
20
|
+
}
|
21
|
+
|
22
|
+
document.addEventListener('turbolinks:load', function(){
|
23
|
+
|
24
|
+
$('#close_side').click(function() {
|
25
|
+
if ($('.ui.side').hasClass('invisible')) {
|
26
|
+
window.localStorage.setItem('invisible', 'false');
|
27
|
+
sidebarSide2();
|
28
|
+
} else {
|
29
|
+
window.localStorage.setItem('invisible', 'true');
|
30
|
+
sidebarSide1();
|
31
|
+
}
|
32
|
+
});
|
33
|
+
|
34
|
+
if (localStorage.getItem('invisible') === 'true') {
|
35
|
+
sidebarSide1();
|
36
|
+
} else {
|
37
|
+
sidebarSide2();
|
38
|
+
}
|
39
|
+
|
40
|
+
});
|
@@ -14,8 +14,8 @@ module TheCommonApi
|
|
14
14
|
def process_errors(model)
|
15
15
|
render json: {
|
16
16
|
errors: model.errors.as_json(full_messages: true),
|
17
|
-
full_messages: model.errors.full_messages.join(
|
18
|
-
}, status:
|
17
|
+
full_messages: model.errors.full_messages.join("\n")
|
18
|
+
}, status: 200
|
19
19
|
end
|
20
20
|
|
21
21
|
def wrap_body
|
@@ -1,4 +1,5 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module RailsCom::AssetsHelper
|
2
3
|
|
3
4
|
def js_load(filename = nil, root: nil, **options)
|
4
5
|
filename ||= "controllers/#{controller_path}/#{action_name}"
|
@@ -27,13 +28,4 @@ module RailsComHelper
|
|
27
28
|
end
|
28
29
|
end
|
29
30
|
|
30
|
-
def simple_format_hash(hash_text, options = {})
|
31
|
-
wrapper_tag = options.fetch(:wrapper_tag, :p)
|
32
|
-
|
33
|
-
hash_text.map do |k, v|
|
34
|
-
text = k.to_s + ': ' + v.to_s
|
35
|
-
content_tag(wrapper_tag, text)
|
36
|
-
end.join("\n\n").html_safe
|
37
|
-
end
|
38
|
-
|
39
31
|
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module RailsCom::CommonHelper
|
3
|
+
|
4
|
+
def simple_format_hash(hash_text, options = {})
|
5
|
+
wrapper_tag = options.fetch(:wrapper_tag, :p)
|
6
|
+
|
7
|
+
hash_text.map do |k, v|
|
8
|
+
text = k.to_s + ': ' + v.to_s
|
9
|
+
content_tag(wrapper_tag, text)
|
10
|
+
end.join("\n\n").html_safe
|
11
|
+
end
|
12
|
+
|
13
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module RailsCom::TimeHelper
|
3
|
+
|
4
|
+
def exact_distance_time(from_time, to_time, options = {})
|
5
|
+
result = TimeHelper.exact_distance_time(from_time, to_time)
|
6
|
+
|
7
|
+
options = {
|
8
|
+
scope: :'datetime.prompts'
|
9
|
+
}.merge!(options)
|
10
|
+
|
11
|
+
I18n.with_options locale: options[:locale], scope: options[:scope] do |locale|
|
12
|
+
str = ''
|
13
|
+
result.each do |k, v|
|
14
|
+
if v > 0
|
15
|
+
str << v.to_s << locale.t(k)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
str
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
data/app/models/state_machine.rb
CHANGED
@@ -1,27 +1,75 @@
|
|
1
1
|
module StateMachine
|
2
2
|
|
3
|
-
#
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
3
|
+
# to defined next_xxx_states in class
|
4
|
+
|
5
|
+
# obj.next_to state: 'xxx'
|
6
|
+
def next_to(options = {})
|
7
|
+
options.each do |column, value|
|
8
|
+
if self.class.method_defined? "next_#{column}_states"
|
9
|
+
_next_state = self.send("next_#{column}_states").first
|
10
|
+
else
|
11
|
+
_next_state = next_state(column)
|
12
|
+
end
|
13
|
+
|
14
|
+
if _next_state == value.to_s
|
15
|
+
assign_attributes(column => value)
|
16
|
+
else
|
17
|
+
error_msg = "Next state is wrong, should be #{_next_state}"
|
18
|
+
errors.add column, error_msg
|
19
|
+
raise ActiveRecord::Rollback, error_msg
|
20
|
+
end
|
8
21
|
end
|
22
|
+
end
|
9
23
|
|
10
|
-
|
11
|
-
|
12
|
-
|
24
|
+
def next_to!(options = {})
|
25
|
+
self.next_to(options, &block)
|
26
|
+
self.save!
|
27
|
+
end
|
13
28
|
|
14
|
-
|
15
|
-
|
29
|
+
def trigger_to(options = {})
|
30
|
+
options.each do |column, value|
|
31
|
+
if self.class.method_defined? "next_#{column}_states"
|
32
|
+
_next_states = self.send "next_#{column}_states"
|
33
|
+
else
|
34
|
+
_next_states = next_states(column)
|
35
|
+
end
|
16
36
|
|
17
|
-
if
|
18
|
-
assign_attributes(
|
19
|
-
save!
|
37
|
+
if _next_states.include?(value.to_s)
|
38
|
+
assign_attributes(column => value)
|
20
39
|
else
|
21
|
-
|
22
|
-
|
40
|
+
error_msg = "Next state is wrong, should be one of #{_next_states.join(', ')}"
|
41
|
+
errors.add column, error_msg
|
42
|
+
raise ActiveRecord::Rollback, error_msg
|
23
43
|
end
|
24
44
|
end
|
25
45
|
end
|
26
46
|
|
47
|
+
def trigger_to!(options = {})
|
48
|
+
self.trigger_to(options, &block)
|
49
|
+
self.save!
|
50
|
+
end
|
51
|
+
|
52
|
+
# obj.next_states(:state) do |result|
|
53
|
+
# result.reject
|
54
|
+
# end
|
55
|
+
def next_states(state_name, &block)
|
56
|
+
_states = self.class.send(state_name.to_s.pluralize)
|
57
|
+
_states = _states.keys
|
58
|
+
_state = self.send(state_name)
|
59
|
+
|
60
|
+
if _state.nil?
|
61
|
+
next_index = 0
|
62
|
+
else
|
63
|
+
i = _states.index(_state)
|
64
|
+
next_index = i + 1
|
65
|
+
end
|
66
|
+
result = _states[next_index..(_states.size - 1)]
|
67
|
+
|
68
|
+
if block_given?
|
69
|
+
yield block.call(result)
|
70
|
+
else
|
71
|
+
result
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
27
75
|
end
|
data/config/locales/en.yml
CHANGED
@@ -0,0 +1,44 @@
|
|
1
|
+
zh:
|
2
|
+
datetime:
|
3
|
+
distance_in_words:
|
4
|
+
half_a_minute: 半分钟
|
5
|
+
less_than_x_seconds:
|
6
|
+
one: 不到1秒
|
7
|
+
other: '不到%{count}秒'
|
8
|
+
x_seconds:
|
9
|
+
one: 1秒
|
10
|
+
other: '%{count}秒'
|
11
|
+
less_than_x_minutes:
|
12
|
+
one: 不到1分钟
|
13
|
+
other: '不到%{count}分钟'
|
14
|
+
x_minutes:
|
15
|
+
one: 1分钟
|
16
|
+
other: '%{count}分钟'
|
17
|
+
about_x_hours:
|
18
|
+
one: 1小时
|
19
|
+
other: '%{count}小时'
|
20
|
+
x_days:
|
21
|
+
one: 1天
|
22
|
+
other: '%{count}天'
|
23
|
+
about_x_months:
|
24
|
+
one: 1个月
|
25
|
+
other: '%{count}个月'
|
26
|
+
x_months:
|
27
|
+
one: 1个月
|
28
|
+
other: '%{count} months'
|
29
|
+
about_x_years:
|
30
|
+
one: 1年
|
31
|
+
other: '%{count} years'
|
32
|
+
over_x_years:
|
33
|
+
one: '超过1年'
|
34
|
+
other: '%{count} 年'
|
35
|
+
almost_x_years:
|
36
|
+
one: 'almost 1 year'
|
37
|
+
other: 'almost %{count} years'
|
38
|
+
prompts:
|
39
|
+
year: 年
|
40
|
+
month: 月
|
41
|
+
day: 日
|
42
|
+
hour: 小时
|
43
|
+
minute: 分钟
|
44
|
+
second: 秒
|
data/config/locales/zh.yml
CHANGED
data/config/routes.rb
CHANGED
data/lib/mina/puma.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
|
-
set :
|
2
|
-
set :
|
1
|
+
set :bundle_more_prefix, -> { "BUNDLE_GEMFILE=#{fetch(:current_path) + '/Gemfile'} #{fetch :bundle_prefix}" }
|
2
|
+
set :puma_cmd, -> { "#{fetch :bundle_more_prefix} puma -e #{fetch :rails_env}" }
|
3
|
+
set :pumactl_cmd, -> { "#{fetch :bundle_more_prefix} pumactl" }
|
3
4
|
set :puma_socket, -> { "#{fetch :current_path}/tmp/pids/puma.pid" }
|
4
5
|
|
5
6
|
namespace :puma do
|
@@ -0,0 +1,27 @@
|
|
1
|
+
set :whenever_name, -> { "#{fetch(:domain)}_#{fetch(:rails_env)}" }
|
2
|
+
|
3
|
+
namespace :whenever do
|
4
|
+
desc 'Clear crontab'
|
5
|
+
task clear: :remote_environment do
|
6
|
+
comment "Clear crontab for #{fetch(:whenever_name)}"
|
7
|
+
in_path fetch(:current_path) do
|
8
|
+
command "#{fetch(:bundle_bin)} exec whenever --clear-crontab #{fetch(:whenever_name)} --set 'environment=#{fetch(:rails_env)}&path=#{fetch(:current_path)}'"
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
desc 'Update crontab'
|
13
|
+
task update: :remote_environment do
|
14
|
+
comment "Update crontab for #{fetch(:whenever_name)}"
|
15
|
+
in_path fetch(:current_path) do
|
16
|
+
command "#{fetch(:bundle_bin)} exec whenever --update-crontab #{fetch(:whenever_name)} --set 'environment=#{fetch(:rails_env)}&path=#{fetch(:current_path)}'"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
desc 'Write crontab'
|
21
|
+
task write: :remote_environment do
|
22
|
+
comment "Write crontab for #{fetch(:whenever_name)}"
|
23
|
+
in_path fetch(:current_path) do
|
24
|
+
command "#{fetch(:bundle_bin)} exec whenever --write-crontab #{fetch(:whenever_name)} --set 'environment=#{fetch(:rails_env)}&path=#{fetch(:current_path)}'"
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
class Array
|
2
|
+
|
3
|
+
# arr = [1, 2, 3]
|
4
|
+
# arr.rjust! 5, nil
|
5
|
+
# => [1, 2, 3, nil, nil]
|
6
|
+
def rjust!(n, x)
|
7
|
+
return self if n < length
|
8
|
+
insert(0, *Array.new([0, n-length].max, x))
|
9
|
+
end
|
10
|
+
|
11
|
+
# arr = [1, 2, 3]
|
12
|
+
# arr.ljust! 5, nil
|
13
|
+
# => [nil, nil, 1, 2, 3]
|
14
|
+
def ljust!(n, x)
|
15
|
+
return self if n < length
|
16
|
+
fill(x, length...n)
|
17
|
+
end
|
18
|
+
|
19
|
+
# arr = [1, 2, 3]
|
20
|
+
# arr.mjust!(5, nil)
|
21
|
+
# => [1, 2, nil, nil, 3]
|
22
|
+
def mjust!(n, x)
|
23
|
+
return self if n < length
|
24
|
+
insert (length / 2.0).ceil, *Array.new(n - length, x)
|
25
|
+
end
|
26
|
+
|
27
|
+
# raw_data = [
|
28
|
+
# { a: 1 },
|
29
|
+
# { a: 2 },
|
30
|
+
# { b: 2 }
|
31
|
+
# ]
|
32
|
+
# raw_data.to_combined_hash
|
33
|
+
# => { a: [1, 2], b: 2 }
|
34
|
+
def to_combined_hash
|
35
|
+
self.reduce({}) do |memo, index|
|
36
|
+
memo.merge(index) { |_, value, default| [value, default] }
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
# raw_data = [
|
41
|
+
# [:a, 1],
|
42
|
+
# [:a, 2],
|
43
|
+
# [:b, 2]
|
44
|
+
# ]
|
45
|
+
# raw_data.to_combined_h
|
46
|
+
# => { a: [1, 2], b: 2 }
|
47
|
+
# todo nested array bug
|
48
|
+
def to_combined_h
|
49
|
+
hash = {}
|
50
|
+
self.each { |x, y| hash[x] = hash[x] ? Array(hash[x]) << y : y }
|
51
|
+
hash
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
@@ -13,7 +13,6 @@ module RailsCom::ModelHelper
|
|
13
13
|
generator.invoke_all
|
14
14
|
end
|
15
15
|
|
16
|
-
|
17
16
|
def column_attributes
|
18
17
|
columns.map do |column|
|
19
18
|
[
|
@@ -27,7 +26,6 @@ module RailsCom::ModelHelper
|
|
27
26
|
end
|
28
27
|
end
|
29
28
|
|
30
|
-
|
31
29
|
def print_table(with_column: false)
|
32
30
|
columns.each do |column|
|
33
31
|
info = with_column ? '# t.column' : '# '
|
@@ -48,7 +46,60 @@ module RailsCom::ModelHelper
|
|
48
46
|
nil
|
49
47
|
end
|
50
48
|
|
51
|
-
|
49
|
+
def sql_table(except: [], only: [], pure: true)
|
50
|
+
if only.size > 0
|
51
|
+
_columns = columns.select { |column| only.include?(column.name) }
|
52
|
+
else
|
53
|
+
_columns = columns.reject { |column| except.include?(column.name) }
|
54
|
+
end
|
55
|
+
|
56
|
+
if pure
|
57
|
+
sql = ""
|
58
|
+
else
|
59
|
+
sql = "CREATE TABLE `#{self.table_name}` (\n"
|
60
|
+
end
|
61
|
+
|
62
|
+
_columns.each do |column|
|
63
|
+
sql << " `#{column.name}` #{column.sql_type}"
|
64
|
+
sql << " COLLATE #{column.collation}" if column.collation
|
65
|
+
sql << " NOT NULL" unless column.null
|
66
|
+
if column.default
|
67
|
+
sql << " DEFAULT '#{column.default}',\n"
|
68
|
+
elsif column.default.nil? && column.null
|
69
|
+
sql << " DEFAULT NULL,\n"
|
70
|
+
else
|
71
|
+
sql << ",\n"
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
sql << " PRIMARY KEY (`#{self.primary_key}`)"
|
52
76
|
|
77
|
+
_indexes = connection.indexes(self.table_name).reject { |index| (index.columns & _columns.map { |col| col.name }).blank? }
|
78
|
+
if _indexes.present?
|
79
|
+
sql << ",\n"
|
80
|
+
else
|
81
|
+
sql << "\n"
|
82
|
+
end
|
83
|
+
_indexes.each_with_index do |obj, index|
|
84
|
+
sql << " KEY `#{obj.name}` ("
|
85
|
+
sql << obj.columns.map { |col| "`#{col}`" }.join(',')
|
86
|
+
|
87
|
+
if index + 1 == _indexes.size
|
88
|
+
sql << ")\n"
|
89
|
+
else
|
90
|
+
sql << "),\n"
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
if pure
|
95
|
+
sql
|
96
|
+
else
|
97
|
+
sql << ")"
|
98
|
+
end
|
99
|
+
end
|
53
100
|
|
54
|
-
|
101
|
+
end
|
102
|
+
|
103
|
+
ActiveSupport.on_load :active_record do
|
104
|
+
extend RailsCom::ModelHelper
|
105
|
+
end
|