rails_com 1.2.0 → 1.2.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +6 -4
  3. data/app/assets/javascripts/rails_com/checkbox.js +59 -0
  4. data/app/assets/javascripts/rails_com/common.js +5 -2
  5. data/app/assets/javascripts/rails_com/fetch_xhr_script.js +3 -37
  6. data/app/assets/javascripts/rails_com/sidebar.js +40 -0
  7. data/app/controllers/common_controller.rb +0 -8
  8. data/app/controllers/concerns/the_common_api.rb +2 -2
  9. data/app/helpers/rails_com/active_helper.rb +1 -0
  10. data/app/helpers/{rails_com_helper.rb → rails_com/assets_helper.rb} +2 -10
  11. data/app/helpers/rails_com/common_helper.rb +13 -0
  12. data/app/helpers/rails_com/time_helper.rb +22 -0
  13. data/app/models/state_machine.rb +63 -15
  14. data/app/views/shared/_locales.html.erb +1 -1
  15. data/config/locales/en.yml +7 -1
  16. data/config/locales/zh.datetime.yml +44 -0
  17. data/config/locales/zh.yml +9 -0
  18. data/config/routes.rb +0 -4
  19. data/lib/mina/puma.rb +3 -2
  20. data/lib/mina/whenever.rb +27 -0
  21. data/lib/rails_com/config.rb +11 -0
  22. data/lib/rails_com/core_ext/array.rb +54 -0
  23. data/lib/rails_com/model_helper.rb +55 -4
  24. data/lib/rails_com/rails_ext/activestorage_attached.rb +32 -0
  25. data/lib/rails_com/rails_ext/persistence_sneakily.rb +11 -0
  26. data/lib/rails_com/rails_ext/scaffold_generator.rb +1 -0
  27. data/lib/rails_com/rails_ext/template_renderer.rb +3 -3
  28. data/lib/rails_com/rails_ext/translation_helper.rb +18 -0
  29. data/lib/rails_com/routes.rb +5 -0
  30. data/lib/rails_com/setting.rb +34 -0
  31. data/lib/rails_com/version.rb +1 -1
  32. data/lib/rails_com.rb +7 -5
  33. data/lib/templates/erb/scaffold/_search_form.html.erb.tt +1 -1
  34. data/lib/templates/erb/scaffold/edit.html.erb.tt +7 -12
  35. data/lib/templates/erb/scaffold/index.html.erb.tt +32 -36
  36. data/lib/templates/erb/scaffold/new.html.erb.tt +8 -12
  37. data/lib/utils/ip_helper.rb +21 -0
  38. data/lib/utils/time_helper.rb +37 -0
  39. metadata +17 -12
  40. data/config/initializers/time_format.rb +0 -1
  41. data/lib/assets/javascripts/semantic.js +0 -11
  42. data/lib/nondigest_assets/fonts/themes/default/assets/fonts/icons.eot +0 -0
  43. data/lib/nondigest_assets/fonts/themes/default/assets/fonts/icons.otf +0 -0
  44. data/lib/nondigest_assets/fonts/themes/default/assets/fonts/icons.svg +0 -947
  45. data/lib/nondigest_assets/fonts/themes/default/assets/fonts/icons.ttf +0 -0
  46. data/lib/nondigest_assets/fonts/themes/default/assets/fonts/icons.woff +0 -0
  47. data/lib/nondigest_assets/fonts/themes/default/assets/fonts/icons.woff2 +0 -0
  48. 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: 91a9e381fa905dd733cdabed0016d6f6826b468e3d9a2d1af8eece1323d88d81
4
- data.tar.gz: 95625b665362ccfea08fb4f9317a521e741adc0f765d0bef2996477aef0cc34c
3
+ metadata.gz: 2ffa9f1ff257d36fdc9bb11415039affae4ee7a1589f7c15f565e911ca6fe33a
4
+ data.tar.gz: 36054a13e2f3a8b7ea8c8130dcb16185612bc8b575c701eaaf0630b6c8f0ce0c
5
5
  SHA512:
6
- metadata.gz: 0ce5ae23bc46a4f2d667db8d8b21ee86b4fa8670a322074857d1cee11b0a6afd7c3e8c8cce0325cc15a6b65742c25dec7b486a48bb964e971df62f9d3b21734c
7
- data.tar.gz: a6f1f3e942c26a68ad460f387146fe58304895fa8c46ac76c9f9053fcbf270ca4cd7288bb0cb5a6d4839275099e18ad1282fe517cfea796e34f52e508cb257c9
6
+ metadata.gz: 27c0ff46020d0a06076a4c085deea1ce604434b97836232c3ccea537b05b20c7be7960cf2dad3786dfa365f1a85994e7f4b8bc68e9a759c7dd8e598a98e31f95
7
+ data.tar.gz: 0d745dbbe1560f2ccfb5fe2a6172ef3180903bec46aa8f40b59d864bb9b447ae8157719c7ed05822086c468a27e82282085e02709720357534af651c247ba130
data/README.md CHANGED
@@ -1,5 +1,5 @@
1
1
  # RailsCom
2
- Short description and motivation.
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
- ## Usage
21
- How to use my plugin.
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
- this.textContent = moment.utc(this.textContent).local().format('YYYY-MM-DD HH:mm:ss');
4
- this.dataset['localized'] = 'true'
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
+ });
@@ -7,12 +7,4 @@ class CommonController < ApplicationController
7
7
  end
8
8
  end
9
9
 
10
- def not_found
11
- params.permit!
12
- RailsCom.not_found_logger.info "#{params[:path]}.#{params[:format]}"
13
-
14
- head :not_found
15
- end
16
-
17
-
18
10
  end
@@ -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: 500
17
+ full_messages: model.errors.full_messages.join("\n")
18
+ }, status: 200
19
19
  end
20
20
 
21
21
  def wrap_body
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module RailsCom::ActiveHelper
2
3
 
3
4
  # active_assert('notice' == 'notice', expected: 'ui info message', unexpected: 'ui negative message')
@@ -1,4 +1,5 @@
1
- module RailsComHelper
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
@@ -1,27 +1,75 @@
1
1
  module StateMachine
2
2
 
3
- # obj = Model.new
4
- # obj.process_to state: 'xxx'
5
- def process_to(options = {})
6
- if options.size > 1
7
- raise 'Only support one column'
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
- options.each do |k, v|
11
- states = k.to_s.pluralize
12
- states = self.class.send(states)
24
+ def next_to!(options = {})
25
+ self.next_to(options, &block)
26
+ self.save!
27
+ end
13
28
 
14
- i = states[self.send(k)]
15
- n = states.key(i+1)
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 n == v.to_s
18
- assign_attributes(k => v)
19
- save!
37
+ if _next_states.include?(value.to_s)
38
+ assign_attributes(column => value)
20
39
  else
21
- errors.add k, 'Next state is wrong'
22
- raise ActiveRecord::Rollback, 'Next state is wrong'
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
@@ -1,5 +1,5 @@
1
1
  <div class="ui simple dropdown item">
2
- <i class="translate icon"></i>
2
+ <i class="globe icon"></i>
3
3
  <%= I18n.locale %>
4
4
  <div class="menu">
5
5
  <%= link_to 'EN', { locale: 'en' }, class: 'item' %>
@@ -22,4 +22,10 @@ en:
22
22
  update: 'Updates %{model}'
23
23
  submit: 'Saves %{model}'
24
24
  q:
25
- submit: 'Search'
25
+ submit: 'Search'
26
+ number:
27
+ human:
28
+ storage_units:
29
+ units:
30
+ h: Hours
31
+ m: Min
@@ -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: 秒
@@ -1,4 +1,13 @@
1
1
  zh:
2
+ errors:
3
+ format: "%{attribute} %{message}"
4
+ messages:
5
+ record_invalid: "验证失败: %{errors}"
6
+ model_invalid: "验证失败: %{errors}"
7
+ required: 必须存在
8
+ blank: 不能为空
9
+ too_short: 长度不够
10
+ taken: 已被占用
2
11
  views:
3
12
  pagination:
4
13
  first: First
data/config/routes.rb CHANGED
@@ -6,7 +6,3 @@ Rails.application.routes.draw do
6
6
  end
7
7
 
8
8
  end
9
-
10
- Rails.application.routes.append do
11
- match '*path' => 'common#not_found', via: :all
12
- end
data/lib/mina/puma.rb CHANGED
@@ -1,5 +1,6 @@
1
- set :puma_cmd, -> { "#{fetch :bundle_prefix} puma -e #{fetch :rails_env}" }
2
- set :pumactl_cmd, -> { "#{fetch :bundle_prefix} pumactl" }
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,11 @@
1
+ module RailsCom
2
+ include ActiveSupport::Configurable
3
+ config_accessor :access_denied_method, :default_admin_emails
4
+
5
+ configure do |config|
6
+ config.ignore_controllers = [
7
+ 'rails/welcome'
8
+ ]
9
+ end
10
+
11
+ 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
- end
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
- ActiveRecord::Base.extend RailsCom::ModelHelper
101
+ end
102
+
103
+ ActiveSupport.on_load :active_record do
104
+ extend RailsCom::ModelHelper
105
+ end