eac_rails_utils 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (57) hide show
  1. checksums.yaml +7 -0
  2. data/Rakefile +18 -0
  3. data/lib/assets/javascripts/currency_field.js +21 -0
  4. data/lib/assets/javascripts/eac_rails_utils.js +6 -0
  5. data/lib/assets/javascripts/input_searchable.js +78 -0
  6. data/lib/assets/javascripts/jMenu.jquery.min.js +12 -0
  7. data/lib/assets/javascripts/jquery.maskMoney.js +409 -0
  8. data/lib/assets/stylesheets/autocomplete.scss +33 -0
  9. data/lib/assets/stylesheets/bootstrap3-dropdown.scss +47 -0
  10. data/lib/assets/stylesheets/eac_rails_utils.scss +44 -0
  11. data/lib/assets/stylesheets/jmenu.scss +78 -0
  12. data/lib/eac/common_form_helper.rb +37 -0
  13. data/lib/eac/common_form_helper/form_builder.rb +88 -0
  14. data/lib/eac/common_form_helper/form_builder/association_select_field.rb +40 -0
  15. data/lib/eac/common_form_helper/form_builder/common_text_fields.rb +18 -0
  16. data/lib/eac/common_form_helper/form_builder/currency_field.rb +39 -0
  17. data/lib/eac/common_form_helper/form_builder/date_field.rb +20 -0
  18. data/lib/eac/common_form_helper/form_builder/fields_for.rb +44 -0
  19. data/lib/eac/common_form_helper/form_builder/radio_select_field.rb +44 -0
  20. data/lib/eac/common_form_helper/form_builder/searchable_association_field.rb +77 -0
  21. data/lib/eac/cpf_validator.rb +60 -0
  22. data/lib/eac/formatter_helper.rb +27 -0
  23. data/lib/eac/htmlbeautifier.rb +25 -0
  24. data/lib/eac/menus_helper.rb +17 -0
  25. data/lib/eac/menus_helper/bootstrap_gui_builder.rb +90 -0
  26. data/lib/eac/menus_helper/data_builder.rb +57 -0
  27. data/lib/eac/menus_helper/gui_builder.rb +51 -0
  28. data/lib/eac/model.rb +87 -0
  29. data/lib/eac/simple_cache.rb +29 -0
  30. data/lib/eac/source_target_fixtures.rb +51 -0
  31. data/lib/eac_rails_utils.rb +29 -0
  32. data/lib/eac_rails_utils/patches/model_attribute_required.rb +31 -0
  33. data/lib/eac_rails_utils/rails/engine.rb +5 -0
  34. data/lib/eac_rails_utils/version.rb +3 -0
  35. data/test/dummy/Rakefile +6 -0
  36. data/test/dummy/app/models/job.rb +4 -0
  37. data/test/dummy/app/models/user.rb +7 -0
  38. data/test/dummy/config.ru +4 -0
  39. data/test/dummy/config/application.rb +12 -0
  40. data/test/dummy/config/boot.rb +4 -0
  41. data/test/dummy/config/database.yml +5 -0
  42. data/test/dummy/config/environment.rb +5 -0
  43. data/test/dummy/config/environments/test.rb +42 -0
  44. data/test/dummy/config/routes.rb +8 -0
  45. data/test/dummy/config/secrets.yml +22 -0
  46. data/test/dummy/db/migrate/20160415125333_create_users.rb +9 -0
  47. data/test/dummy/db/migrate/20160415143123_create_jobs.rb +7 -0
  48. data/test/dummy/db/migrate/20160415143229_add_job_to_users.rb +5 -0
  49. data/test/dummy/db/schema.rb +25 -0
  50. data/test/lib/eac/common_form_helper_test.rb +31 -0
  51. data/test/lib/eac/cpf_validator_test.rb +33 -0
  52. data/test/lib/eac/formatter_helper_test.rb +19 -0
  53. data/test/lib/eac/model_test.rb +76 -0
  54. data/test/lib/eac/simple_cache_test.rb +56 -0
  55. data/test/lib/eac_rails_utils/patches/model_attribute_required_test.rb +39 -0
  56. data/test/test_helper.rb +11 -0
  57. metadata +189 -0
@@ -0,0 +1,51 @@
1
+ module Eac
2
+ module MenusHelper
3
+ class GuiBuilder
4
+ def initialize(view)
5
+ @view = view
6
+ end
7
+
8
+ def build(entries, options = {})
9
+ fail "Argument \"entries\" is not a array" unless entries.is_a?(Array)
10
+ @view.content_tag(:ul, options) do
11
+ b = ActiveSupport::SafeBuffer.new
12
+ entries.map { |v| menu_entry(v) }.each { |e| b << e }
13
+ b
14
+ end
15
+ end
16
+
17
+ private
18
+
19
+ def menu_entry(entry)
20
+ if entry[:type] == :group
21
+ menu_group(entry[:label], entry[:children])
22
+ elsif entry[:type] == :item
23
+ menu_item(entry[:label], entry[:path], entry[:options])
24
+ else
25
+ fail "Unknown menu entry type: \"#{entry[:type]}\""
26
+ end
27
+ end
28
+
29
+ def menu_group(label, children)
30
+ @view.content_tag(:li) do
31
+ @view.link_to(label) << build(children)
32
+ end
33
+ end
34
+
35
+ def menu_item(label, path, options)
36
+ @view.content_tag(:li) do
37
+ @view.link_to(label, path, menu_item_link_options(options))
38
+ end
39
+ end
40
+
41
+ def menu_item_link_options(options)
42
+ options = options.dup
43
+ if options.key?(:link_method)
44
+ options[:method] = options[:link_method]
45
+ options.delete(:link_method)
46
+ end
47
+ options
48
+ end
49
+ end
50
+ end
51
+ end
data/lib/eac/model.rb ADDED
@@ -0,0 +1,87 @@
1
+ module Eac
2
+ module Model
3
+ # Adiciona as mensagens de erro de record. As mensagens de uma coluna X em record
4
+ # serão adicionadas na coluna X em self. Se options[:default_column] for especificado
5
+ # as mensagens da coluna X de record em que X não existe em self serão adicionadas
6
+ # na coluna options[:default_column].
7
+ # Um array de colunas pode ser passado em options[:skip] de colunas em record que não
8
+ # terão suas falhas adicionadas.
9
+ def fetch_record_errors(record, options = {})
10
+ record.errors.keys.each do |column|
11
+ fetch_column_errors(record, column, column, options)
12
+ end
13
+ end
14
+
15
+ # Similar a fetch_record_errors, mas torna possível especificar, através de mapping,
16
+ # colunas-alvo em self com nomes diferentes das colunas-fonte em record.
17
+ # mapping tem o formato { record_column => self_column }.
18
+ def fetch_record_errors_by_mapping(record, mapping, options = {})
19
+ mapping.each do |record_column, self_column|
20
+ fetch_column_errors(record, record_column, self_column, options)
21
+ end
22
+ end
23
+
24
+ def fetch_column_errors(record, record_column, self_column, options = {})
25
+ return if options[:skip] && options[:skip].include?(record_column)
26
+ record.errors[record_column].each do |message|
27
+ fetch_error_column_message(self_column, message, options[:default_column],
28
+ "#{record.class.human_attribute_name(record_column)}: ")
29
+ end
30
+ end
31
+
32
+ # Verifica se uma coluna existe.
33
+ def column?(column)
34
+ respond_to?(column) && respond_to?("#{column}=")
35
+ end
36
+
37
+ def save_or_raise
38
+ unless save
39
+ fail "Falha ao tentar salvar #{self.class.name}: #{errors_to_string}"
40
+ end
41
+ self
42
+ end
43
+
44
+ private
45
+
46
+ def fetch_error_column_message(column, message, default_column, default_column_message_prefix)
47
+ build_self_columns_messages(column, message, default_column,
48
+ default_column_message_prefix).each do |k, v|
49
+ if column?(k)
50
+ add_error_message(k, v)
51
+ break
52
+ end
53
+ end
54
+ end
55
+
56
+ # Adiciona uma mensagem de erro a uma coluna somente se a coluna
57
+ # ainda não a possui
58
+ def add_error_message(column, message)
59
+ return if errors[column].include?(message)
60
+ errors.add(column, message)
61
+ end
62
+
63
+ # Produz uma lista de campos-mensagens, em ordem de preferência,
64
+ # que podem receber uma mensagem de falha.
65
+ def build_self_columns_messages(column, message, default_column,
66
+ default_column_message_prefix)
67
+ r = { column => message }
68
+ m = /^(.+)_id$/.match(column)
69
+ if m
70
+ r[m[1]] = message
71
+ else
72
+ r["#{column}_id"] = message
73
+ end
74
+ r[default_column] = "#{default_column_message_prefix}#{message}" if default_column
75
+ r
76
+ end
77
+
78
+ def errors_to_string
79
+ b = ''
80
+ errors.messages.each do |field, messages|
81
+ b += ' / ' if b != ''
82
+ b += field.to_s + ': ' + messages.to_s
83
+ end
84
+ b
85
+ end
86
+ end
87
+ end
@@ -0,0 +1,29 @@
1
+ module Eac
2
+ module SimpleCache
3
+ def method_missing(method, *args, &block)
4
+ uncached_method = "#{method}_uncached"
5
+ if respond_to?(uncached_method, true)
6
+ call_method_with_cache(uncached_method, args, &block)
7
+ else
8
+ super
9
+ end
10
+ end
11
+
12
+ def reset_cache
13
+ @cache_keys = nil
14
+ end
15
+
16
+ private
17
+
18
+ def call_method_with_cache(method, args, &block)
19
+ fail 'Não é possível realizar o cache de métodos com bloco' if block
20
+ key = ([method] + args).join('@@@')
21
+ cache_keys[key] = send(method, *args) unless cache_keys.key?(key)
22
+ cache_keys[key]
23
+ end
24
+
25
+ def cache_keys
26
+ @cache_keys ||= {}
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,51 @@
1
+ # encoding: UTF-8
2
+ # frozen_string_literal: true
3
+
4
+ require 'yaml'
5
+
6
+ module Eac
7
+ class SourceTargetFixtures
8
+ attr_reader :fixtures_directory
9
+
10
+ def initialize(fixtures_directory)
11
+ @fixtures_directory = fixtures_directory
12
+ end
13
+
14
+ def source_target_files(&block)
15
+ sources_targets_basenames.each do |test_basename|
16
+ block.call(source_file(test_basename), target_file(test_basename))
17
+ end
18
+ end
19
+
20
+ private
21
+
22
+ def target_file(basename)
23
+ fixture_file(basename, 'target')
24
+ end
25
+
26
+ def source_file(basename)
27
+ fixture_file(basename, 'source')
28
+ end
29
+
30
+ def fixture_file(basename, suffix)
31
+ prefix = "#{basename}.#{suffix}"
32
+ Dir.foreach(fixtures_directory) do |item|
33
+ next if item == '.' || item == '..'
34
+ return File.expand_path(item, fixtures_directory) if item.starts_with?(prefix)
35
+ end
36
+ fail "\"#{prefix}\" not found (Basename: #{basename}, Suffix: #{suffix})"
37
+ end
38
+
39
+ def sources_targets_basenames
40
+ basenames = []
41
+ Dir.foreach(fixtures_directory) do |item|
42
+ next if item == '.' || item == '..'
43
+ if /^(.+)\.(?:source|target)(?:\..+)?$/ =~ File.basename(item)
44
+ basenames << Regexp.last_match(1)
45
+ end
46
+ end
47
+ fail "\"#{fixtures_directory}\" não possui nenhum arquivo para teste." if basenames.empty?
48
+ basenames
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,29 @@
1
+ module EacRailsUtils
2
+ require 'nested_form_fields'
3
+
4
+ require 'eac_rails_utils/patches/model_attribute_required'
5
+ require 'eac_rails_utils/rails/engine'
6
+ require 'eac/cpf_validator'
7
+ require 'eac/formatter_helper'
8
+ require 'eac/common_form_helper/form_builder/association_select_field'
9
+ require 'eac/common_form_helper/form_builder/common_text_fields'
10
+ require 'eac/common_form_helper/form_builder/currency_field'
11
+ require 'eac/common_form_helper/form_builder/date_field'
12
+ require 'eac/common_form_helper/form_builder/fields_for'
13
+ require 'eac/common_form_helper/form_builder/radio_select_field'
14
+ require 'eac/common_form_helper/form_builder/searchable_association_field'
15
+ require 'eac/common_form_helper/form_builder'
16
+ require 'eac/common_form_helper'
17
+ require 'eac/htmlbeautifier'
18
+ require 'eac/menus_helper'
19
+ require 'eac/menus_helper/bootstrap_gui_builder'
20
+ require 'eac/menus_helper/data_builder'
21
+ require 'eac/menus_helper/gui_builder'
22
+ require 'eac/model'
23
+ require 'eac/simple_cache'
24
+ require 'eac/source_target_fixtures'
25
+
26
+ ActionView::Base.send :include, Eac::CommonFormHelper
27
+ ActionView::Base.send :include, Eac::FormatterHelper
28
+ ActionView::Base.send :include, Eac::MenusHelper
29
+ end
@@ -0,0 +1,31 @@
1
+ require 'active_record'
2
+
3
+ module EacRailsUtils
4
+ module Patches
5
+ module ModelAttributeRequired
6
+ def self.included(base)
7
+ base.extend ClassMethods
8
+ base.include InstanceMethods
9
+ end
10
+
11
+ module ClassMethods
12
+ def column_required?(column)
13
+ m = new
14
+ m.validate
15
+ m.errors.key?(column.to_sym)
16
+ end
17
+ end
18
+
19
+ module InstanceMethods
20
+ def attribute_required?(column)
21
+ self.class.column_required?(column)
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
27
+
28
+ [::ActiveRecord::Base, ::ActiveModel::Model].each do |c|
29
+ next if c.included_modules.include? ::EacRailsUtils::Patches::ModelAttributeRequired
30
+ c.include ::EacRailsUtils::Patches::ModelAttributeRequired
31
+ end
@@ -0,0 +1,5 @@
1
+ module EacRailsUtils
2
+ module Rails
3
+ class Engine < ::Rails::Engine; end
4
+ end
5
+ end
@@ -0,0 +1,3 @@
1
+ module EacRailsUtils
2
+ VERSION = '0.0.1'
3
+ end
@@ -0,0 +1,6 @@
1
+ # Add your own tasks in files placed in lib/tasks ending in .rake,
2
+ # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
3
+
4
+ require File.expand_path('../config/application', __FILE__)
5
+
6
+ Rails.application.load_tasks
@@ -0,0 +1,4 @@
1
+ class Job < ActiveRecord::Base
2
+ has_many :users
3
+ accepts_nested_attributes_for :users, reject_if: :all_blank, allow_destroy: true
4
+ end
@@ -0,0 +1,7 @@
1
+ class User < ActiveRecord::Base
2
+ belongs_to :job
3
+
4
+ validates :job, presence: true
5
+ validates :password, presence: true
6
+ validates :email, format: { with: /\A[^@\s]+@[^@\s]+\z/ }
7
+ end
@@ -0,0 +1,4 @@
1
+ # This file is used by Rack-based servers to start the application.
2
+
3
+ require ::File.expand_path('../config/environment', __FILE__)
4
+ run Rails.application
@@ -0,0 +1,12 @@
1
+ require File.expand_path('../boot', __FILE__)
2
+
3
+ require 'rails/all'
4
+
5
+ Bundler.require(*Rails.groups)
6
+ require 'eac_rails_utils'
7
+
8
+ module Dummy
9
+ class Application < Rails::Application
10
+ config.active_record.raise_in_transactional_callbacks = true
11
+ end
12
+ end
@@ -0,0 +1,4 @@
1
+ # Set up gems listed in the Gemfile.
2
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../../../Gemfile', __FILE__)
3
+
4
+ require 'bundler/setup' if File.exist?(ENV['BUNDLE_GEMFILE'])
@@ -0,0 +1,5 @@
1
+ test:
2
+ adapter: sqlite3
3
+ pool: 5
4
+ timeout: 5000
5
+ database: db/test.sqlite3
@@ -0,0 +1,5 @@
1
+ # Load the Rails application.
2
+ require File.expand_path('../application', __FILE__)
3
+
4
+ # Initialize the Rails application.
5
+ Rails.application.initialize!
@@ -0,0 +1,42 @@
1
+ Rails.application.configure do
2
+ # Settings specified here will take precedence over those in config/application.rb.
3
+
4
+ # The test environment is used exclusively to run your application's
5
+ # test suite. You never need to work with it otherwise. Remember that
6
+ # your test database is "scratch space" for the test suite and is wiped
7
+ # and recreated between test runs. Don't rely on the data there!
8
+ config.cache_classes = true
9
+
10
+ # Do not eager load code on boot. This avoids loading your whole application
11
+ # just for the purpose of running a single test. If you are using a tool that
12
+ # preloads Rails for running tests, you may have to set it to true.
13
+ config.eager_load = false
14
+
15
+ # Configure static file server for tests with Cache-Control for performance.
16
+ config.serve_static_files = true
17
+ config.static_cache_control = 'public, max-age=3600'
18
+
19
+ # Show full error reports and disable caching.
20
+ config.consider_all_requests_local = true
21
+ config.action_controller.perform_caching = false
22
+
23
+ # Raise exceptions instead of rendering exception templates.
24
+ config.action_dispatch.show_exceptions = false
25
+
26
+ # Disable request forgery protection in test environment.
27
+ config.action_controller.allow_forgery_protection = false
28
+
29
+ # Tell Action Mailer not to deliver emails to the real world.
30
+ # The :test delivery method accumulates sent emails in the
31
+ # ActionMailer::Base.deliveries array.
32
+ config.action_mailer.delivery_method = :test
33
+
34
+ # Randomize the order test cases are executed.
35
+ config.active_support.test_order = :random
36
+
37
+ # Print deprecation notices to the stderr.
38
+ config.active_support.deprecation = :stderr
39
+
40
+ # Raises error for missing translations
41
+ # config.action_view.raise_on_missing_translations = true
42
+ end
@@ -0,0 +1,8 @@
1
+ Rails.application.routes.draw do
2
+ resources :jobs do
3
+ collection do
4
+ get 'search'
5
+ end
6
+ end
7
+ resources :users
8
+ end
@@ -0,0 +1,22 @@
1
+ # Be sure to restart your server when you modify this file.
2
+
3
+ # Your secret key is used for verifying the integrity of signed cookies.
4
+ # If you change this key, all old signed cookies will become invalid!
5
+
6
+ # Make sure the secret is at least 30 characters and all random,
7
+ # no regular words or you'll be exposed to dictionary attacks.
8
+ # You can use `rake secret` to generate a secure secret key.
9
+
10
+ # Make sure the secrets in this file are kept private
11
+ # if you're sharing your code publicly.
12
+
13
+ development:
14
+ secret_key_base: 50d3bce23e309d961dafde3edfa89be2713718a5e2fb75b6c3e1f61826230921535243d2f221b8cecebeaceccb574a1e74fbbf3b89a9d53758ac988950f1753c
15
+
16
+ test:
17
+ secret_key_base: 75f37392ef7726b50b4ce117bd6a7eca7cdc299608e256f7ca163b14032559217364d41b7c091483ce02179a18c956f6e076331a611c0500f2862f83979a6c16
18
+
19
+ # Do not keep production secrets in the repository,
20
+ # instead read values from the environment.
21
+ production:
22
+ secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>
@@ -0,0 +1,9 @@
1
+ class CreateUsers < ActiveRecord::Migration
2
+ def change
3
+ create_table :users do |t|
4
+ t.string :name
5
+ t.string :email
6
+ t.string :password
7
+ end
8
+ end
9
+ end