eac_rails_utils 0.8.0 → 0.11.0

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.
Files changed (83) hide show
  1. checksums.yaml +4 -4
  2. data/Rakefile +2 -0
  3. data/{lib/eac → app/helpers/eac_rails_utils}/common_form_helper.rb +8 -1
  4. data/{lib/eac → app/helpers/eac_rails_utils}/common_form_helper/form_builder.rb +12 -2
  5. data/{lib/eac → app/helpers/eac_rails_utils}/common_form_helper/form_builder/association_select_field.rb +5 -2
  6. data/{lib/eac → app/helpers/eac_rails_utils}/common_form_helper/form_builder/common_text_fields.rb +4 -3
  7. data/{lib/eac → app/helpers/eac_rails_utils}/common_form_helper/form_builder/currency_field.rb +14 -12
  8. data/{lib/eac → app/helpers/eac_rails_utils}/common_form_helper/form_builder/date_field.rb +3 -1
  9. data/{lib/eac → app/helpers/eac_rails_utils}/common_form_helper/form_builder/fields_for.rb +3 -1
  10. data/{lib/eac → app/helpers/eac_rails_utils}/common_form_helper/form_builder/file_field.rb +2 -1
  11. data/{lib/eac → app/helpers/eac_rails_utils}/common_form_helper/form_builder/radio_select_field.rb +5 -2
  12. data/{lib/eac → app/helpers/eac_rails_utils}/common_form_helper/form_builder/searchable_association_field.rb +7 -3
  13. data/{lib/eac → app/helpers/eac_rails_utils}/common_form_helper/form_builder/select_field.rb +3 -1
  14. data/{lib/eac → app/helpers/eac_rails_utils}/common_form_helper/form_builder/time_field.rb +2 -1
  15. data/{lib/eac → app/helpers/eac_rails_utils}/common_form_helper/form_builder/year_month_field.rb +2 -1
  16. data/app/helpers/eac_rails_utils/data_table_helper.rb +13 -0
  17. data/{lib/eac → app/helpers/eac_rails_utils}/data_table_helper/column.rb +6 -3
  18. data/{lib/eac → app/helpers/eac_rails_utils}/data_table_helper/data_table.rb +13 -11
  19. data/{lib/eac → app/helpers/eac_rails_utils}/data_table_helper/setup.rb +3 -2
  20. data/app/helpers/eac_rails_utils/formatter_helper.rb +2 -0
  21. data/app/helpers/eac_rails_utils/links_helper.rb +12 -2
  22. data/{lib/eac → app/helpers/eac_rails_utils}/menus_helper.rb +10 -2
  23. data/{lib/eac → app/helpers/eac_rails_utils}/menus_helper/bootstrap_gui_builder.rb +8 -5
  24. data/{lib/eac → app/helpers/eac_rails_utils}/menus_helper/data_builder.rb +7 -2
  25. data/{lib/eac → app/helpers/eac_rails_utils}/menus_helper/gui_builder.rb +6 -3
  26. data/app/helpers/eac_rails_utils/open_graph_protocol_helper.rb +2 -0
  27. data/{lib/eac → app/validators/eac_rails_utils}/cpf_validator.rb +8 -4
  28. data/{lib/eac → app/validators/eac_rails_utils}/no_presence_validator.rb +3 -3
  29. data/lib/assets/javascripts/jMenu.jquery.min.js +12 -12
  30. data/lib/eac_rails_utils.rb +3 -41
  31. data/lib/eac_rails_utils/engine.rb +3 -0
  32. data/lib/{eac → eac_rails_utils}/htmlbeautifier.rb +3 -1
  33. data/lib/eac_rails_utils/models.rb +9 -0
  34. data/lib/eac_rails_utils/models/attribute_required.rb +43 -0
  35. data/lib/eac_rails_utils/models/fetch_errors.rb +92 -0
  36. data/lib/eac_rails_utils/models/inequality_queries.rb +39 -0
  37. data/lib/eac_rails_utils/models/tableless.rb +97 -0
  38. data/lib/eac_rails_utils/models/test_utils.rb +65 -0
  39. data/lib/eac_rails_utils/patches.rb +9 -0
  40. data/lib/eac_rails_utils/patches/action_controller_base.rb +3 -0
  41. data/lib/eac_rails_utils/version.rb +2 -1
  42. data/test/dummy/Rakefile +3 -1
  43. data/test/dummy/app/models/job.rb +2 -0
  44. data/test/dummy/app/models/user.rb +6 -0
  45. data/test/dummy/config.ru +2 -0
  46. data/test/dummy/config/application.rb +3 -1
  47. data/test/dummy/config/boot.rb +3 -1
  48. data/test/dummy/config/environment.rb +3 -1
  49. data/test/dummy/config/environments/test.rb +2 -0
  50. data/test/dummy/config/routes.rb +2 -0
  51. data/test/dummy/db/migrate/20160415125333_create_users.rb +2 -0
  52. data/test/dummy/db/migrate/20160415143123_create_jobs.rb +2 -0
  53. data/test/dummy/db/migrate/20160415143229_add_job_to_users.rb +2 -0
  54. data/test/{lib/eac → helpers/eac_rails_utils}/common_form_helper_test.rb +4 -2
  55. data/test/{lib/eac/data_table_test_helper.rb → helpers/eac_rails_utils/data_table_test_helper_test.rb} +4 -3
  56. data/test/{app/helpers → helpers}/eac_rails_utils/formatter_helper_test.rb +1 -0
  57. data/test/lib/eac_rails_utils/{patches/model_attribute_required_test.rb → models/attribute_required_test.rb} +3 -0
  58. data/test/lib/eac_rails_utils/models/fetch_errors_test.rb +80 -0
  59. data/test/lib/eac_rails_utils/models/tableless_test.rb +25 -0
  60. data/test/test_helper.rb +3 -1
  61. data/test/{lib/eac → validators}/cpf_validator_test.rb +4 -2
  62. metadata +91 -98
  63. data/lib/eac/data_table_helper.rb +0 -12
  64. data/lib/eac/inequality_queries.rb +0 -36
  65. data/lib/eac/model.rb +0 -87
  66. data/lib/eac/parsers/files_test.rb +0 -63
  67. data/lib/eac/source_target_fixtures.rb +0 -66
  68. data/lib/eac/test_utils.rb +0 -56
  69. data/lib/eac_rails_utils/patches/model_attribute_required.rb +0 -31
  70. data/lib/eac_rails_utils/patches/ofx_parser.rb +0 -42
  71. data/lib/eac_rails_utils/tableless_model.rb +0 -90
  72. data/test/lib/eac/model_test.rb +0 -76
  73. data/test/lib/eac/parsers/files_test_test.rb +0 -27
  74. data/test/lib/eac/parsers/ok_test_files/a.source.yaml +0 -1
  75. data/test/lib/eac/parsers/ok_test_files/a.target.yaml +0 -1
  76. data/test/lib/eac/parsers/ok_test_files/b.source.yaml +0 -1
  77. data/test/lib/eac/parsers/ok_test_files/b.target.yaml +0 -1
  78. data/test/lib/eac/source_target_fixtures_test.rb +0 -41
  79. data/test/lib/eac/source_target_fixtures_test_files/a.source.html +0 -1
  80. data/test/lib/eac/source_target_fixtures_test_files/a.target.yaml +0 -1
  81. data/test/lib/eac/source_target_fixtures_test_files/b.source.html +0 -1
  82. data/test/lib/eac/source_target_fixtures_test_files/c.target.yaml +0 -1
  83. data/test/lib/eac_rails_utils/tableless_model_test.rb +0 -23
@@ -1,4 +1,6 @@
1
- module Eac
1
+ # frozen_string_literal: true
2
+
3
+ module EacRailsUtils
2
4
  module MenusHelper
3
5
  # http://bootsnipp.com/snippets/featured/multi-level-dropdown-menu-bs3
4
6
  class BootstrapGuiBuilder
@@ -8,7 +10,8 @@ module Eac
8
10
  end
9
11
 
10
12
  def build(entries)
11
- fail "Argument \"entries\" is not a array" unless entries.is_a?(Array)
13
+ raise 'Argument "entries" is not a array' unless entries.is_a?(Array)
14
+
12
15
  @view.content_tag(:ul, class: "nav navbar-nav #{@options[:class]}".strip) do
13
16
  menu_entries(entries)
14
17
  end
@@ -28,12 +31,12 @@ module Eac
28
31
  elsif entry[:type] == :item
29
32
  menu_item(entry)
30
33
  else
31
- fail "Unknown menu entry type: \"#{entry[:type]}\""
34
+ raise "Unknown menu entry type: \"#{entry[:type]}\""
32
35
  end
33
36
  end
34
37
 
35
38
  def menu_group(entry)
36
- if entry[:level] == 0
39
+ if entry[:level].zero?
37
40
  menu_group_root(entry)
38
41
  else
39
42
  menu_group_sub(entry)
@@ -82,7 +85,7 @@ module Eac
82
85
  options[:method] = options[:link_method]
83
86
  options.delete(:link_method)
84
87
  end
85
- options[:class] = "#{@options[:button_class]}".strip if entry[:level] == 0
88
+ options[:class] = (@options[:button_class]).to_s.strip if entry[:level].zero?
86
89
  options
87
90
  end
88
91
  end
@@ -1,4 +1,6 @@
1
- module Eac
1
+ # frozen_string_literal: true
2
+
3
+ module EacRailsUtils
2
4
  module MenusHelper
3
5
  class DataBuilder
4
6
  def initialize(view)
@@ -12,7 +14,8 @@ module Eac
12
14
  private
13
15
 
14
16
  def build_entries(entries, level)
15
- fail 'Argument "entries" is not a hash' unless entries.is_a?(Hash)
17
+ raise 'Argument "entries" is not a hash' unless entries.is_a?(Hash)
18
+
16
19
  r = entries.map { |k, v| build_entry(k, v, level) }.select { |e| e }
17
20
  r.empty? ? nil : r
18
21
  end
@@ -28,12 +31,14 @@ module Eac
28
31
  def build_group(label, menu_entries, level)
29
32
  e = build_entries(menu_entries, level + 1)
30
33
  return nil unless e
34
+
31
35
  { type: :group, label: label, children: e, level: level }
32
36
  end
33
37
 
34
38
  def build_item(label, value, level)
35
39
  path, options = menu_item_options(value)
36
40
  return nil unless can_access_path?(path, options[:link_method])
41
+
37
42
  { type: :item, label: label, path: path, options: options, level: level }
38
43
  end
39
44
 
@@ -1,4 +1,6 @@
1
- module Eac
1
+ # frozen_string_literal: true
2
+
3
+ module EacRailsUtils
2
4
  module MenusHelper
3
5
  class GuiBuilder
4
6
  def initialize(view)
@@ -6,7 +8,8 @@ module Eac
6
8
  end
7
9
 
8
10
  def build(entries, options = {})
9
- fail "Argument \"entries\" is not a array" unless entries.is_a?(Array)
11
+ raise 'Argument "entries" is not a array' unless entries.is_a?(Array)
12
+
10
13
  @view.content_tag(:ul, options) do
11
14
  b = ActiveSupport::SafeBuffer.new
12
15
  entries.map { |v| menu_entry(v) }.each { |e| b << e }
@@ -22,7 +25,7 @@ module Eac
22
25
  elsif entry[:type] == :item
23
26
  menu_item(entry[:label], entry[:path], entry[:options])
24
27
  else
25
- fail "Unknown menu entry type: \"#{entry[:type]}\""
28
+ raise "Unknown menu entry type: \"#{entry[:type]}\""
26
29
  end
27
30
  end
28
31
 
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module EacRailsUtils
3
4
  module OpenGraphProtocolHelper
4
5
  OGP_META_DEFAULT_PREFIX = 'og'
@@ -89,6 +90,7 @@ module EacRailsUtils
89
90
 
90
91
  def tag
91
92
  return ::ActiveSupport::SafeBuffer.new unless content?
93
+
92
94
  view.tag(:meta, prefix: view.ogp_prefix, property: property_value, content: content)
93
95
  end
94
96
  end
@@ -1,7 +1,10 @@
1
- module Eac
1
+ # frozen_string_literal: true
2
+
3
+ module EacRailsUtils
2
4
  class CpfValidator < ActiveModel::EachValidator
3
5
  def validate_each(record, attribute, value)
4
6
  return if Cpf.new(value).valid?
7
+
5
8
  record.errors[attribute] << (options[:message] ||
6
9
  'CPF inválido (9 caracteres, somente dígitos)')
7
10
  end
@@ -13,6 +16,7 @@ module Eac
13
16
 
14
17
  def valid?
15
18
  return false if input_invalid?
19
+
16
20
  digito_verificador1_calculo == values[9] && digito_verificador2_calculo == values[10]
17
21
  end
18
22
 
@@ -25,8 +29,8 @@ module Eac
25
29
  end
26
30
 
27
31
  def null?
28
- %w(12345678909 11111111111 22222222222 33333333333 44444444444 55555555555
29
- 66666666666 77777777777 88888888888 99999999999 00000000000).member?(digits.join)
32
+ %w[12345678909 11111111111 22222222222 33333333333 44444444444 55555555555
33
+ 66666666666 77777777777 88888888888 99999999999 00000000000].member?(digits.join)
30
34
  end
31
35
 
32
36
  def digits
@@ -53,7 +57,7 @@ module Eac
53
57
  c -= 1
54
58
  end
55
59
  s -= (11 * (s / 11))
56
- (s == 0 || s == 1) ? 0 : 11 - s
60
+ [0, 1].include?(s) ? 0 : 11 - s
57
61
  end
58
62
  end
59
63
  end
@@ -1,11 +1,11 @@
1
-
2
-
3
1
  # frozen_string_literal: true
4
- module Eac
2
+
3
+ module EacRailsUtils
5
4
  # https://stackoverflow.com/questions/10070786/rails-3-validation-presence-false
6
5
  class NoPresenceValidator < ActiveModel::EachValidator
7
6
  def validate_each(record, attribute, _value)
8
7
  return if record.send(attribute).blank?
8
+
9
9
  record.errors[attribute] << (options[:message] || 'must be blank')
10
10
  end
11
11
  end
@@ -1,12 +1,12 @@
1
- /************************************************************************
2
- *************************************************************************
3
- @Name : jMenu - jQuery Plugin
4
- @Revison : 2.0
5
- @Date : 08/2013
6
- @Author : ALPIXEL - (www.myjqueryplugins.com - www.alpixel.fr)
7
- @Support : FF, IE7, IE8, MAC Firefox, MAC Safari
8
- @License : Open Source - MIT License : http://www.opensource.org/licenses/mit-license.php
9
-
10
- **************************************************************************
11
- *************************************************************************/
12
- (function(e){e.jMenu={defaults:{ulWidth:"auto",absoluteTop:33,absoluteLeft:0,TimeBeforeOpening:100,TimeBeforeClosing:100,animatedText:true,paddingLeft:7,openClick:false,effects:{effectSpeedOpen:150,effectSpeedClose:150,effectTypeOpen:"slide",effectTypeClose:"slide",effectOpen:"swing",effectClose:"swing"}},init:function(t){opts=e.extend({},e.jMenu.defaults,t);if(opts.ulWidth=="auto")$width=e(".fNiv").outerWidth(false);else $width=opts.ulWidth;e(".jMenu li").each(function(){var t=e(this).find("a:first"),n=e(this).find("ul");if(e.jMenu._IsParent(t)){t.addClass("isParent");var r=t.next(),i=t.position();if(e(this).hasClass("jmenu-level-0"))r.css({top:i.top+opts.absoluteTop,left:i.left+opts.absoluteLeft,width:$width});else r.css({top:i.top,left:i.left+$width,width:$width});if(!opts.openClick)e(this).bind({mouseenter:function(){if(e(this).hasClass("jmenu-level-0")){i=e(this).position();r.css({left:i.left+opts.absoluteLeft,top:i.top+opts.absoluteTop})}e.jMenu._show(r)},mouseleave:function(){e.jMenu._closeList(r)}});else e(this).bind({click:function(t){t.preventDefault();e.jMenu._show(r)},mouseleave:function(){e.jMenu._closeList(r)}})}})},_show:function(e){switch(opts.effects.effectTypeOpen){case"slide":e.stop(true,true).delay(opts.TimeBeforeOpening).slideDown(opts.effects.effectSpeedOpen,opts.effects.effectOpen);break;case"fade":e.stop(true,true).delay(opts.TimeBeforeOpening).fadeIn(opts.effects.effectSpeedOpen,opts.effects.effectOpen);break;default:e.stop(true,true).delay(opts.TimeBeforeOpening).show()}},_closeList:function(e){switch(opts.effects.effectTypeClose){case"slide":e.stop(true,true).delay(opts.TimeBeforeClosing).slideUp(opts.effects.effectSpeedClose,opts.effects.effectClose);break;case"fade":e.stop(true,true).delay(opts.TimeBeforeClosing).fadeOut(opts.effects.effectSpeedClose,opts.effects.effectClose);break;default:e.delay(opts.TimeBeforeClosing).hide()}},_animateText:function(t){var n=parseInt(t.css("padding-left"));t.hover(function(){e(this).stop(true,false).animate({paddingLeft:n+opts.paddingLeft},100)},function(){e(this).stop(true,false).animate({paddingLeft:n},100)})},_IsParent:function(e){if(e.next().is("ul"))return true;else return false},_isReadable:function(){if(e(".jmenu-level-0").length>0)return true;else return false},_error:function(){alert("jMenu plugin can't be initialized. Please, check you have the '.jmenu-level-0' class on your first level <li> elements.")}};jQuery.fn.jMenu=function(t){e(this).addClass("jMenu");e(this).children("li").addClass("jmenu-level-0").children("a").addClass("fNiv");if(e.jMenu._isReadable()){e.jMenu.init(t)}else{e.jMenu._error()}}})(jQuery)
1
+ /************************************************************************
2
+ *************************************************************************
3
+ @Name : jMenu - jQuery Plugin
4
+ @Revison : 2.0
5
+ @Date : 08/2013
6
+ @Author : ALPIXEL - (www.myjqueryplugins.com - www.alpixel.fr)
7
+ @Support : FF, IE7, IE8, MAC Firefox, MAC Safari
8
+ @License : Open Source - MIT License : http://www.opensource.org/licenses/mit-license.php
9
+
10
+ **************************************************************************
11
+ *************************************************************************/
12
+ (function(e){e.jMenu={defaults:{ulWidth:"auto",absoluteTop:33,absoluteLeft:0,TimeBeforeOpening:100,TimeBeforeClosing:100,animatedText:true,paddingLeft:7,openClick:false,effects:{effectSpeedOpen:150,effectSpeedClose:150,effectTypeOpen:"slide",effectTypeClose:"slide",effectOpen:"swing",effectClose:"swing"}},init:function(t){opts=e.extend({},e.jMenu.defaults,t);if(opts.ulWidth=="auto")$width=e(".fNiv").outerWidth(false);else $width=opts.ulWidth;e(".jMenu li").each(function(){var t=e(this).find("a:first"),n=e(this).find("ul");if(e.jMenu._IsParent(t)){t.addClass("isParent");var r=t.next(),i=t.position();if(e(this).hasClass("jmenu-level-0"))r.css({top:i.top+opts.absoluteTop,left:i.left+opts.absoluteLeft,width:$width});else r.css({top:i.top,left:i.left+$width,width:$width});if(!opts.openClick)e(this).bind({mouseenter:function(){if(e(this).hasClass("jmenu-level-0")){i=e(this).position();r.css({left:i.left+opts.absoluteLeft,top:i.top+opts.absoluteTop})}e.jMenu._show(r)},mouseleave:function(){e.jMenu._closeList(r)}});else e(this).bind({click:function(t){t.preventDefault();e.jMenu._show(r)},mouseleave:function(){e.jMenu._closeList(r)}})}})},_show:function(e){switch(opts.effects.effectTypeOpen){case"slide":e.stop(true,true).delay(opts.TimeBeforeOpening).slideDown(opts.effects.effectSpeedOpen,opts.effects.effectOpen);break;case"fade":e.stop(true,true).delay(opts.TimeBeforeOpening).fadeIn(opts.effects.effectSpeedOpen,opts.effects.effectOpen);break;default:e.stop(true,true).delay(opts.TimeBeforeOpening).show()}},_closeList:function(e){switch(opts.effects.effectTypeClose){case"slide":e.stop(true,true).delay(opts.TimeBeforeClosing).slideUp(opts.effects.effectSpeedClose,opts.effects.effectClose);break;case"fade":e.stop(true,true).delay(opts.TimeBeforeClosing).fadeOut(opts.effects.effectSpeedClose,opts.effects.effectClose);break;default:e.delay(opts.TimeBeforeClosing).hide()}},_animateText:function(t){var n=parseInt(t.css("padding-left"));t.hover(function(){e(this).stop(true,false).animate({paddingLeft:n+opts.paddingLeft},100)},function(){e(this).stop(true,false).animate({paddingLeft:n},100)})},_IsParent:function(e){if(e.next().is("ul"))return true;else return false},_isReadable:function(){if(e(".jmenu-level-0").length>0)return true;else return false},_error:function(){alert("jMenu plugin can't be initialized. Please, check you have the '.jmenu-level-0' class on your first level <li> elements.")}};jQuery.fn.jMenu=function(t){e(this).addClass("jMenu");e(this).children("li").addClass("jmenu-level-0").children("a").addClass("fNiv");if(e.jMenu._isReadable()){e.jMenu.init(t)}else{e.jMenu._error()}}})(jQuery)
@@ -1,45 +1,7 @@
1
1
  # frozen_string_literal: true
2
- require 'active_support/dependencies'
3
2
 
4
- module EacRailsUtils
5
- require 'activemodel/associations'
6
- require 'nested_form_fields'
7
- require 'ofx-parser'
8
- require 'virtus'
9
-
10
- require 'eac_rails_utils/patches/action_controller_base'
11
- require 'eac_rails_utils/patches/model_attribute_required'
12
- require 'eac_rails_utils/patches/ofx_parser'
13
- require 'eac_rails_utils/engine'
14
- require 'eac_rails_utils/tableless_model'
15
- require 'eac/cpf_validator'
16
- require 'eac/common_form_helper/form_builder/association_select_field'
17
- require 'eac/common_form_helper/form_builder/common_text_fields'
18
- require 'eac/common_form_helper/form_builder/currency_field'
19
- require 'eac/common_form_helper/form_builder/date_field'
20
- require 'eac/common_form_helper/form_builder/fields_for'
21
- require 'eac/common_form_helper/form_builder/file_field'
22
- require 'eac/common_form_helper/form_builder/radio_select_field'
23
- require 'eac/common_form_helper/form_builder/searchable_association_field'
24
- require 'eac/common_form_helper/form_builder/select_field'
25
- require 'eac/common_form_helper/form_builder/time_field'
26
- require 'eac/common_form_helper/form_builder/year_month_field'
27
- require 'eac/common_form_helper/form_builder'
28
- require 'eac/common_form_helper'
29
- require 'eac/data_table_helper'
30
- require 'eac/htmlbeautifier'
31
- require 'eac/inequality_queries'
32
- require 'eac/menus_helper'
33
- require 'eac/menus_helper/bootstrap_gui_builder'
34
- require 'eac/menus_helper/data_builder'
35
- require 'eac/menus_helper/gui_builder'
36
- require 'eac/model'
37
- require 'eac/no_presence_validator'
38
- require 'eac/parsers/files_test'
39
- require 'eac/source_target_fixtures'
40
- require 'eac/test_utils'
3
+ require 'eac_ruby_utils/require_sub'
41
4
 
42
- ActionView::Base.send :include, Eac::CommonFormHelper
43
- ActionView::Base.send :include, Eac::DataTableHelper
44
- ActionView::Base.send :include, Eac::MenusHelper
5
+ module EacRailsUtils
6
+ ::EacRubyUtils.require_sub __FILE__
45
7
  end
@@ -1,4 +1,7 @@
1
1
  # frozen_string_literal: true
2
+
3
+ require 'nested_form_fields'
4
+
2
5
  module EacRailsUtils
3
6
  class Engine < ::Rails::Engine; end
4
7
  end
@@ -1,6 +1,8 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'htmlbeautifier'
2
4
 
3
- module Eac
5
+ module EacRailsUtils
4
6
  class Htmlbeautifier
5
7
  def self.beautify(string)
6
8
  ::HtmlBeautifier.beautify(string, tab_stops: 2) + "\n"
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'eac_ruby_utils/require_sub'
4
+
5
+ module EacRailsUtils
6
+ module Models
7
+ ::EacRubyUtils.require_sub __FILE__
8
+ end
9
+ end
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'active_support/concern'
4
+
5
+ module EacRailsUtils
6
+ module Models
7
+ module AttributeRequired
8
+ extend ::ActiveSupport::Concern
9
+
10
+ class << self
11
+ def required?(model_class_or_record, attribute)
12
+ model = model_class_or_record_to_model(model_class_or_record)
13
+ record = model.new
14
+ record.validate
15
+ record.errors.key?(attribute.to_sym)
16
+ end
17
+
18
+ private
19
+
20
+ def model_class_or_record_to_model(model_class_or_record)
21
+ model_class_or_record.is_a?(::Class) ? model_class_or_record : model_class_or_record.class
22
+ end
23
+ end
24
+
25
+ included do
26
+ extend ClassMethods
27
+ include InstanceMethods
28
+ end
29
+
30
+ module ClassMethods
31
+ def column_required?(column)
32
+ ::EacRailsUtils::Models::AttributeRequired.required?(self, column)
33
+ end
34
+ end
35
+
36
+ module InstanceMethods
37
+ def attribute_required?(column)
38
+ self.class.column_required?(column)
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,92 @@
1
+ # frozen_string_literal: true
2
+
3
+ module EacRailsUtils
4
+ module Models
5
+ module FetchErrors
6
+ # Adiciona as mensagens de erro de record. As mensagens de uma coluna X em record
7
+ # serão adicionadas na coluna X em self. Se options[:default_column] for especificado
8
+ # as mensagens da coluna X de record em que X não existe em self serão adicionadas
9
+ # na coluna options[:default_column].
10
+ # Um array de colunas pode ser passado em options[:skip] de colunas em record que não
11
+ # terão suas falhas adicionadas.
12
+ def fetch_record_errors(record, options = {})
13
+ record.errors.keys.each do |column|
14
+ fetch_column_errors(record, column, column, options)
15
+ end
16
+ end
17
+
18
+ # Similar a fetch_record_errors, mas torna possível especificar, através de mapping,
19
+ # colunas-alvo em self com nomes diferentes das colunas-fonte em record.
20
+ # mapping tem o formato { record_column => self_column }.
21
+ def fetch_record_errors_by_mapping(record, mapping, options = {})
22
+ mapping.each do |record_column, self_column|
23
+ fetch_column_errors(record, record_column, self_column, options)
24
+ end
25
+ end
26
+
27
+ def fetch_column_errors(record, record_column, self_column, options = {})
28
+ return if options[:skip]&.include?(record_column)
29
+
30
+ record.errors[record_column].each do |message|
31
+ fetch_error_column_message(self_column, message, options[:default_column],
32
+ "#{record.class.human_attribute_name(record_column)}: ")
33
+ end
34
+ end
35
+
36
+ # Verifica se uma coluna existe.
37
+ def column?(column)
38
+ respond_to?(column) && respond_to?("#{column}=")
39
+ end
40
+
41
+ def save_or_raise
42
+ raise "Falha ao tentar salvar #{self.class.name}: #{errors_to_string}" unless save
43
+
44
+ self
45
+ end
46
+
47
+ private
48
+
49
+ def fetch_error_column_message(column, message, default_column, default_column_message_prefix)
50
+ build_self_columns_messages(column, message, default_column,
51
+ default_column_message_prefix).each do |k, v|
52
+ if column?(k)
53
+ add_error_message(k, v)
54
+ break
55
+ end
56
+ end
57
+ end
58
+
59
+ # Adiciona uma mensagem de erro a uma coluna somente se a coluna
60
+ # ainda não a possui
61
+ def add_error_message(column, message)
62
+ return if errors[column].include?(message)
63
+
64
+ errors.add(column, message)
65
+ end
66
+
67
+ # Produz uma lista de campos-mensagens, em ordem de preferência,
68
+ # que podem receber uma mensagem de falha.
69
+ def build_self_columns_messages(column, message, default_column,
70
+ default_column_message_prefix)
71
+ r = { column => message }
72
+ m = /^(.+)_id$/.match(column)
73
+ if m
74
+ r[m[1]] = message
75
+ else
76
+ r["#{column}_id"] = message
77
+ end
78
+ r[default_column] = "#{default_column_message_prefix}#{message}" if default_column
79
+ r
80
+ end
81
+
82
+ def errors_to_string
83
+ b = ''
84
+ errors.messages.each do |field, messages|
85
+ b += ' / ' if b != ''
86
+ b += field.to_s + ': ' + messages.to_s
87
+ end
88
+ b
89
+ end
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ module EacRailsUtils
4
+ module Models
5
+ # == Example:
6
+ #
7
+ # Note: model Product has a attribute "foo" Date, Time or Number:
8
+ #
9
+ # class Product
10
+ # include ::EacRailsUtils::Models::InequalityQueries
11
+ #
12
+ # add_inequality_queries(:foo)
13
+ # end
14
+ #
15
+ # This add the following scopes:
16
+ #
17
+ # Product.by_foo_gt(value) # Equivalent to Product.where("foo > ?", value)
18
+ # Product.by_foo_gteq(value) # Equivalent to Product.where("foo >= ?", value)
19
+ # Product.by_foo_lt(value) # Equivalent to Product.where("foo < ?", value)
20
+ # Product.by_foo_lteq(value) # Equivalent to Product.where("foo <= ?", value)
21
+ module InequalityQueries
22
+ class << self
23
+ def included(base)
24
+ base.extend(ClassMethods)
25
+ end
26
+ end
27
+
28
+ module ClassMethods
29
+ def add_inequality_queries(attribute)
30
+ %w[gt gteq lt lteq].each do |ineq|
31
+ scope "by_#{attribute}_#{ineq}", lambda { |v|
32
+ where(arel_table[attribute].send(ineq, v))
33
+ }
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end