c80_shared 0.1.62 → 0.1.63

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 (48) hide show
  1. checksums.yaml +4 -4
  2. data/app/serializers/boat_serializer.rb +5 -0
  3. data/lib/c80_shared/version.rb +1 -1
  4. data/lib/c80_shared.rb +1 -1
  5. data/scratch_105___02.txt +13 -0
  6. metadata +3 -44
  7. data/app/repositories/accounts/admin_account_repository.rb +0 -35
  8. data/app/repositories/accounts/central_agent_account_repository.rb +0 -46
  9. data/app/repositories/accounts/client_account_repository.rb +0 -43
  10. data/app/repositories/accounts/manager_account_repository.rb +0 -35
  11. data/app/repositories/accounts/manager_guest_account_repository.rb +0 -35
  12. data/app/repositories/accounts/moderator_account_repository.rb +0 -35
  13. data/app/schemas/base.rb +0 -69
  14. data/app/schemas/base_boat_schema.rb +0 -235
  15. data/app/schemas/central_agent/save_boat_schema.rb +0 -57
  16. data/app/services/abstract_prices_service.rb +0 -70
  17. data/app/services/boats/boat_prices_save_service.rb +0 -81
  18. data/app/services/boats/boat_sale_prices_save_service.rb +0 -60
  19. data/app/services/boats/dimension_service.rb +0 -44
  20. data/app/services/central_agent/save_boat_service.rb +0 -111
  21. data/app/services/lease/create_broadcast_inquiry_service.rb +0 -62
  22. data/app/services/lease/destroy_inquiry_service.rb +0 -5
  23. data/config/initializers/core_ext/active_record_log_subscriber.rb +0 -60
  24. data/config/initializers/core_ext/string.rb +0 -62
  25. data/lib/dry/errors.rb +0 -77
  26. data/lib/dry/rule.rb +0 -75
  27. data/lib/dry/rules/and.rb +0 -13
  28. data/lib/dry/rules/between.rb +0 -20
  29. data/lib/dry/rules/binary.rb +0 -18
  30. data/lib/dry/rules/collection.rb +0 -18
  31. data/lib/dry/rules/composite.rb +0 -21
  32. data/lib/dry/rules/equal.rb +0 -20
  33. data/lib/dry/rules/format.rb +0 -20
  34. data/lib/dry/rules/greater_than.rb +0 -20
  35. data/lib/dry/rules/greater_than_or_equal.rb +0 -20
  36. data/lib/dry/rules/included.rb +0 -20
  37. data/lib/dry/rules/length_between.rb +0 -20
  38. data/lib/dry/rules/length_equal.rb +0 -20
  39. data/lib/dry/rules/less_than.rb +0 -20
  40. data/lib/dry/rules/less_than_or_equal.rb +0 -20
  41. data/lib/dry/rules/max_length.rb +0 -20
  42. data/lib/dry/rules/min_length.rb +0 -20
  43. data/lib/dry/rules/not_equal.rb +0 -20
  44. data/lib/dry/rules/or.rb +0 -15
  45. data/lib/dry/rules/present.rb +0 -23
  46. data/lib/dry/rules/then.rb +0 -15
  47. data/lib/dry/rules_factory.rb +0 -134
  48. data/lib/dry/schema.rb +0 -148
@@ -1,57 +0,0 @@
1
- require_relative '../base_boat_schema'
2
-
3
- module Schemas
4
- module CentralAgent
5
- class SaveBoatSchema < Schemas::BaseBoatSchema
6
- def schema
7
- boat_schema = super
8
- boat_schema[:required] = %i[
9
- name
10
- boat_type_id
11
- ]
12
-
13
- boat_schema[:properties][:boat_photos_attributes] = {
14
- type: [:null, :hash],
15
- cast: ->(value) { nullify_empty(value) }
16
- }
17
-
18
- # второй вариант реализации property boat_length, который присутствует в базовой схеме
19
- %i[boat_length_metrics boat_beam_metrics boat_draft_metrics].product([:meters, :ft]).map { |f,d| '%s_%s' % [f,d] }.each do |prop|
20
- boat_schema[:properties][prop.to_sym] = {
21
- type: %i[null string number],
22
- cast: ->(value) do
23
- val = value.is_a?(String) ? value.split(/[, ]/).join : value
24
- to_float val
25
- end
26
- }
27
- end
28
-
29
- boat_schema
30
- end
31
-
32
-
33
- def validate_additional
34
- validate_boat_photos
35
- validate_prices_and_rent_prices
36
- validate_rent_prices
37
- validate_length
38
- validate_location
39
- validate_guests_total
40
- # validate_guest_cabins
41
- validate_crew_total
42
- end
43
-
44
- def validate_boat_photos
45
- errors.add :boat_photos, I18n.t('errors.boat.boat_photos_attributes.blank') unless boat_photos_attributes.present?
46
- end
47
-
48
-
49
- def validate_length
50
- val = boat_length_metrics_meters || boat_length_metrics_ft
51
- unless val.present? && val > 0 && val < 1000
52
- errors.add(:boat_length_metrics, I18n.t('errors.messages.invalid'))
53
- end
54
- end
55
- end
56
- end
57
- end
@@ -1,70 +0,0 @@
1
- class AbstractPricesService
2
-
3
- attr_reader :built_prices
4
-
5
- def initialize(all_currencies = ::Dicts::Currency::ALL2) # all_currencies - список валют, в которых надо сохранить цены
6
- @all_currencies = all_currencies
7
- _reset_ivars
8
- end
9
-
10
- private
11
-
12
- def _model
13
- raise NotImplementedError
14
- end
15
-
16
- def _fields_for_create
17
- raise NotImplementedError
18
- end
19
-
20
- def _save(prices) # помещаем в базу всё одним запросом
21
- filtered = prices.select { |el| !el[:_delete] && el[:value].to_i != 0 } # игнорируя цены, которые были помечены "к удалению" или те, у которых значение 0 (0 можно подавать, если хотим "удалить" цену продажи)
22
- return if filtered.size.zero?
23
-
24
- values = filtered.map do |p|
25
- _fields_for_create.map do |field|
26
- p[field.to_sym]
27
- end.compact * ','
28
- end * '),('
29
- values = '(%s)' % values
30
- sql = 'INSERT INTO %s(%s) VALUES %s' % [_model.table_name, _fields_for_create * ',', values]
31
- ActiveRecord::Base.connection.execute sql
32
-
33
- filtered
34
- end
35
-
36
- # из базы удаляем все записи, принадлежащие данной лодке
37
- # т.к. считаем, что с формы приходит полная картина по ценам
38
- # кроме того, юзер может просто изменить, например, период в уже
39
- # существующей строке с ценами, которую он видит на экране
40
- def _delete_existing_records(boat_id)
41
- sql = 'DELETE FROM %s WHERE boat_id = %s' % [_model.table_name, boat_id]
42
- ActiveRecord::Base.connection.execute sql
43
- end
44
-
45
- def _build_other(price) # отталкиваясь от валюты входных данных, рассчитываем "те же" цены в других валютах
46
- return if price[:_delete] || price[:value].to_i == 0 # игнорируя цены, которые были помечены "к удалению" или те, у которых значение 0 (0 можно подавать, если хотим "удалить" цену продажи)
47
-
48
- incoming_curr = ::Dicts::Currency.find(price[:currency_id])
49
- currs_to_build = @all_currencies - [incoming_curr]
50
- rates = Currency.fresh(incoming_curr.index).rates
51
- rates = JSON.parse(rates)['rates']
52
-
53
- currs_to_build.each do |curr|
54
- rate = rates[curr.index]
55
- res = price.clone
56
- res[:currency_id] = curr.id
57
- res[:value] = res[:value].to_f * rate
58
- res[:is_orig] = false
59
- @built_prices << res
60
- end
61
- end
62
-
63
- def _delete_bad_values(prices)
64
- prices.delete_if { |price| price[:value].nil? || price[:value].to_f.zero? }
65
- end
66
-
67
- def _reset_ivars
68
- @built_prices = []
69
- end
70
- end
@@ -1,81 +0,0 @@
1
- require_relative '../abstract_prices_service'
2
-
3
- module Boats
4
- #
5
- # spec/services/boat/boat_prices_save_service_spec.rb
6
- #
7
- class BoatPricesSaveService < ::AbstractPricesService
8
-
9
- attr_reader :is_for_rent
10
-
11
- def self.perform(boat, params)
12
- new.perform(boat, params)
13
- end
14
-
15
- def perform(boat, prices = nil)
16
- _reset_ivars
17
- return false if prices.nil?
18
-
19
- boat_prices_params = prices.deep_dup # Rails deep_dup https://apidock.com/rails/Hash/deep_dup
20
- boat_prices_params = boat_prices_params.map { |bp| bp.symbolize_keys }
21
- filtered = _delete_bad_values boat_prices_params
22
- return false if filtered.size.zero? # взаимодействия с базой не будет, если все цены с "плохими" значениями
23
-
24
- filtered.each do |bp| # bp = {uom_id, season_id, currency_id, duration, value, discount}
25
- bp[:boat_id] = boat.id
26
- bp[:is_orig] = true
27
- bp[:value] = bp[:value].is_a?(String) ? bp[:value].split(/[, ]/).join : bp[:value] # с формы может прийти строка, сгруппированная по разрадям, вида "100,100,222"
28
- bp[:duration] = format('%.1f', bp[:duration])
29
- bp[:discount] = bp[:discount].to_f # с формы может прийти пустая строка ''
30
- bp[:created_at] = '\'%s\'' % Time.now.to_s(:db)
31
- _build_other bp
32
- end
33
-
34
- filtered2 = _del_duplicates(filtered + @built_prices)
35
- return false if filtered2.size.zero?
36
-
37
- saved = nil
38
- ActiveRecord::Base.transaction do
39
- _delete_existing_records boat.id
40
- saved = _save filtered2
41
- end
42
-
43
- @is_for_rent = _detect_for_rent saved
44
- true
45
- end
46
-
47
- private
48
-
49
- def _model
50
- BoatPrice
51
- end
52
-
53
- def _fields_for_create
54
- @fields_for_create ||= %w'boat_id uom_id duration season_id is_orig discount currency_id value created_at'
55
- end
56
-
57
-
58
- def _delete_bad_values(prices)
59
- prices.delete_if do |price|
60
- price[:value].nil? || price[:value].to_f.zero? || format('%.1f', price[:duration].to_f) == '0.0'
61
- end
62
- end
63
-
64
- def _del_duplicates(params) # подстраховываемся, вдруг форма прислала что-то не то
65
- grouped = params.group_by { |row| [row[:duration].to_f, row[:uom_id], row[:season_id], row[:currency_id]] } # убираем из params массива дубликаты согласно уникальному индексу в db
66
- grouped.map {|_, v| v.first }
67
- end
68
-
69
- def _reset_ivars
70
- @is_for_rent = nil
71
- super
72
- end
73
-
74
- def _detect_for_rent(saved_prices)
75
- return 0 if saved_prices.nil?
76
- # noinspection RubySimplifyBooleanInspection
77
- !!saved_prices.select { |bp| !bp[:_delete] }.size.nonzero? ? 1 : 0
78
- end
79
-
80
- end
81
- end
@@ -1,60 +0,0 @@
1
- require_relative '../abstract_prices_service'
2
-
3
- module Boats
4
- #
5
- # [spec/services/boat/boat_sale_price_save_service_spec.rb]
6
- #
7
- class BoatSalePricesSaveService < ::AbstractPricesService
8
-
9
- attr_reader :is_for_sale
10
-
11
- def self.perform(boat_id, price)
12
- new.perform boat_id, price
13
- end
14
-
15
- def perform(boat_id, price = nil)
16
- _reset_ivars
17
- return false if price.nil?
18
-
19
- sp = price.dup
20
- sp[:boat_id] = boat_id
21
- sp[:is_orig] = true
22
- sp[:value] = sp[:value].is_a?(String) ? sp[:value].split(/[, ]/).join : sp[:value].to_i # с формы может прийти строка, сгруппированная по разрадям, вида "100,100,222" + тут же превращаем nil в 0
23
- sp[:discount] = sp[:discount].present? ? sp[:discount] : 0
24
- sp[:created_at] = '\'%s\'' % Time.now.to_s(:db)
25
- _build_other sp
26
-
27
- filtered2 = @built_prices + [sp]
28
- saved = nil
29
- ActiveRecord::Base.transaction do
30
- _delete_existing_records boat_id
31
- saved = _save filtered2
32
- end
33
-
34
- @is_for_sale = _detect_for_sale saved
35
- true
36
- end
37
-
38
- private
39
-
40
- def _model
41
- BoatSalePrice
42
- end
43
-
44
- def _fields_for_create
45
- @fields_for_create ||= %w'boat_id currency_id value discount is_orig created_at'
46
- end
47
-
48
- def _reset_ivars
49
- @is_for_sale = nil
50
- super
51
- end
52
-
53
- def _detect_for_sale(saved_prices)
54
- return 0 if saved_prices.nil?
55
- # noinspection RubySimplifyBooleanInspection
56
- !!saved_prices.select { |bp| bp[:value].to_i != 0 }.size.nonzero? ? 1 : 0
57
- end
58
-
59
- end
60
- end
@@ -1,44 +0,0 @@
1
- module Boats
2
- class DimensionService
3
-
4
- def initialize model
5
- @model = model
6
- end
7
-
8
- def calculate_boat_attributes default_dimension
9
-
10
- attributes = [:boat_length_metrics, :boat_beam_metrics, :boat_draft_metrics, :boat_gross_tonage]
11
-
12
- available_dimensions(default_dimension).each do |available_dimension|
13
-
14
- # puts "#{available_dimension} #{default_dimension}"
15
- dimension_value = Dimension::COMPARISON[default_dimension.to_sym][available_dimension.to_sym]
16
-
17
- attributes.each do |attribute|
18
- attribute_dimension = attribute.to_s + "_#{available_dimension}"
19
- attribute_default_dimension = attribute.to_s + "_#{default_dimension}"
20
- default_dimension_value = @model.attributes[attribute_default_dimension.downcase]
21
-
22
- if default_dimension_value
23
- calculated_dimension = default_dimension_value * dimension_value
24
- @model.send("#{attribute_dimension}=", calculated_dimension)
25
- # puts "#{default_dimension_value} #{default_dimension} is #{calculated_dimension} #{available_dimension}"
26
- else
27
- @model.send("#{attribute_dimension}=", nil)
28
- end
29
- end
30
- end
31
-
32
- end
33
-
34
- def available_dimensions default_dimension
35
- available_dimensions = []
36
- I18n::t('static.dimensions').select do |dimension|
37
- next if dimension[:id] == default_dimension
38
- available_dimensions << dimension[:id]
39
- end
40
- available_dimensions
41
- end
42
-
43
- end
44
- end
@@ -1,111 +0,0 @@
1
- module CentralAgent
2
- class SaveBoatService
3
-
4
- attr_reader :errors
5
-
6
- def initialize
7
- _reset_ivars
8
- end
9
-
10
- # @param [Hash] boat_params
11
- # @param [Hash] cookies example: {... "currency"=>"USD", "dimension"=>"ft", "volume"=>"liters", "business"=>"rent", "language"=>"en"}
12
- #
13
- def perform(boat_params, cookies, current_user, state: Boat::STATE_PREMODERATED)
14
- _reset_ivars
15
-
16
- @schema = ::Schemas::CentralAgent::SaveBoatSchema.new boat_params.dup # проверяем параметры, пришедшие с формы
17
- unless @schema.valid?
18
- @errors = @schema.errors.messages
19
- return false
20
- end
21
-
22
- if boat_params[:id].present?
23
- _update_boat(@schema.attributes, cookies)
24
- else
25
- _create_boat(@schema.attributes, cookies, current_user, state)
26
- end
27
-
28
- true
29
- end
30
-
31
- private
32
-
33
- def _create_boat(boat_params, cookies, current_user, state) # TODO:: проверить и доработать при необходимости (ref /home/scout/git/get-the-boat/app/services/boat_register_service.rb)
34
- prms = _fuck_params boat_params
35
-
36
- boat = Boat.new
37
- boat.assign_attributes prms
38
- boat.state = state
39
-
40
- _handle_boat_attributes(boat, cookies)
41
-
42
- ActiveRecord::Base.transaction do
43
- boat.users << current_user
44
-
45
- boat.send :set_slug
46
- boat.save validate: false
47
- boat.update_attribute(:boat_photo_id, boat.boat_photos.first.id) # TODO:: реализовать назначение главного фото (пока же на скорую руку делаем первую фотку главной)
48
- _save_prices boat
49
- end
50
- end
51
-
52
- def _update_boat(boat_params, cookies) # TODO:: реализовать назначение главного фото (в админке, например, приходит такое: "boat"=>{"boat_photo_id"=>"41434"})
53
- # _fuck_params - подгоняем под active_record (перегоняем массив в хэш)
54
- #boat_locs2 = boat_params[:boat_locations_attributes].compact.map { |attr| [attr[:id], attr] }.to_h
55
- #prms = boat_params.except(:rent_prices, :sale_price, :boat_locations_attributes) # с формы из кабинета, в отличии от админки, приходит длина в виде "boat_length_metrics_ft" => "12.0"
56
- #prms[:boat_locations_attributes] = boat_locs2
57
- prms = _fuck_params boat_params
58
-
59
- boat = Boat.find boat_params[:id]
60
- boat.assign_attributes prms
61
-
62
- _handle_boat_attributes(boat, cookies)
63
-
64
- ActiveRecord::Base.transaction do
65
- boat.send :set_slug
66
- boat.save validate: false
67
- _save_prices boat
68
- boat.cancel if boat.state == ::Boat::STATE_APPROVED.to_s # кто знает, что там наизменял агент в своей лодке, вдруг фотки с телефонами загрузил?
69
- end
70
- end
71
-
72
- # boat_params - это атрибуты схемы
73
- def _fuck_params(boat_params)
74
- # подгоняем под active_record (перегоняем массив в хэш)
75
- boat_locs2 = boat_params[:boat_locations_attributes].compact.map { |attr| [(attr[:id] || -(rand*1000).to_i), attr] }.to_h
76
- prms = boat_params.except(:rent_prices, :sale_price, :boat_locations_attributes, :main_boat_photo_id) # с формы из кабинета, в отличии от админки, приходит длина в виде "boat_length_metrics_ft" => "12.0"
77
- prms[:boat_photo_id] = boat_params[:main_boat_photo_id]
78
- prms[:boat_locations_attributes] = boat_locs2
79
- prms
80
- end
81
-
82
- def _handle_boat_attributes(boat, cookies)
83
- dimension_service = ::Boats::DimensionService.new(boat) # присланные измерения переведём в другие единицы измерения
84
- dimension_service.calculate_boat_attributes(cookies[:dimension])
85
-
86
- # volume_service = VolumeService.new(boat)
87
- # volume_service.calculate_boat_attributes(cookies[:volume])
88
- end
89
-
90
- # сохраним цены аренды и цену продажи
91
- def _save_prices(boat)
92
- service = ::Boats::BoatPricesSaveService.new
93
- result = service.perform boat, @schema.attributes[:rent_prices]
94
-
95
- if result && boat.for_rent != service.is_for_rent # result = true - обязательное условие
96
- boat.update_columns for_rent: service.is_for_rent
97
- end
98
-
99
- service = ::Boats::BoatSalePricesSaveService.new
100
- result = service.perform boat.id, @schema.attributes[:sale_price]
101
-
102
- if result && boat.for_sale != service.is_for_sale # result = true - обязательное условие
103
- boat.update_columns for_sale: service.is_for_sale
104
- end
105
- end
106
-
107
- def _reset_ivars
108
- @errors = { }
109
- end
110
- end
111
- end
@@ -1,62 +0,0 @@
1
- module Lease
2
- #
3
- # Если заявка создаётся НЕ со страницы лодки - используется этот сервис
4
- #
5
- class CreateBroadcastInquiryService
6
-
7
- attr_reader :inquiry, :errors
8
-
9
- def initialize
10
- _reset_instance_variables
11
- end
12
-
13
- def perform(client_account, params)
14
- _reset_instance_variables
15
-
16
- @inquiry = ::Lease::Inquiry.new
17
- _assign_attributes(client_account, params)
18
- return false unless @inquiry.valid?
19
-
20
- inquiry_profile = ::Lease::InquiryProfile.new inquiry: @inquiry
21
-
22
- @inquiry.transaction do
23
- @inquiry.save!
24
- inquiry_profile.save!
25
- end
26
-
27
- true
28
- end
29
-
30
- protected
31
-
32
- def _assign_attributes(client_account, params)
33
- @inquiry.client_account = client_account
34
- @inquiry.address = params[:address]
35
- @inquiry.latitude = params[:latitude]
36
- @inquiry.longitude = params[:longitude]
37
- @inquiry.from = params[:from]
38
- @inquiry.to = params[:to]
39
- @inquiry.name = params[:name]
40
- @inquiry.phone_number = params[:phone_number]
41
- @inquiry.is_skippered = params[:is_skippered]
42
- @inquiry.comments = params[:comments]
43
- @inquiry.need_transfer = params[:need_transfer]
44
- @inquiry.watersports = params[:watersports]
45
- @inquiry.guests = params[:guests]
46
- @inquiry.kids = params[:kids]
47
- @inquiry.boat_type_ids = params[:boat_types] # fuckin' rent_form.rb
48
-
49
- if params[:my_price].present? && !params[:my_price].to_i.zero?
50
- @inquiry.my_price = params[:my_price]
51
- @inquiry.my_price_currency = params[:my_price_currency]
52
- @inquiry.is_my_price = true
53
- end
54
- end
55
-
56
- def _reset_instance_variables
57
- @errors = { }
58
- @inquiry = nil
59
- end
60
-
61
- end
62
- end
@@ -1,5 +0,0 @@
1
- module Lease
2
- class DestroyInquiryService
3
-
4
- end
5
- end
@@ -1,60 +0,0 @@
1
- # Разукрашиваем SQL в логе рельсы.
2
- # Патч, взятый из activerecord-5.1.6
3
- # https://blog.bigbinary.com/2016/06/27/rails-5-makes-sql-statements-even-more-colorful.html
4
- #
5
- if ActiveRecord.version <= Gem::Version.new('5.1.6')
6
-
7
- module ActiveRecord
8
- class LogSubscriber < ActiveSupport::LogSubscriber
9
-
10
- def sql(event)
11
- self.class.runtime += event.duration
12
- return unless logger.debug?
13
-
14
- payload = event.payload
15
-
16
- return if IGNORE_PAYLOAD_NAMES.include?(payload[:name])
17
-
18
- name = "#{payload[:name]} (#{event.duration.round(1)}ms)"
19
- sql = payload[:sql]
20
- binds = nil
21
-
22
- unless (payload[:binds] || []).empty?
23
- binds = " " + payload[:binds].map {|col, v|
24
- render_bind(col, v)
25
- }.inspect
26
- end
27
-
28
- name = color(name, CYAN, true)
29
- sql = color(sql, sql_color(sql), true) # <--- изменения только тут
30
-
31
- debug " #{name} #{sql}#{binds}\n"
32
- end
33
-
34
- private
35
-
36
- def sql_color(sql) # <--- и новый приватный метод
37
- case sql
38
- when /\A\s*rollback/mi
39
- RED
40
- when /select .*for update/mi, /\A\s*lock/mi
41
- WHITE
42
- when /\A\s*select/i
43
- BLUE
44
- when /\A\s*insert/i
45
- GREEN
46
- when /\A\s*update/i
47
- YELLOW
48
- when /\A\s*delete/i
49
- RED
50
- when /transaction\s*\Z/i
51
- CYAN
52
- else
53
- MAGENTA
54
- end
55
- end
56
-
57
- end
58
- end
59
-
60
- end
@@ -1,62 +0,0 @@
1
- class String
2
-
3
- def clear_query
4
- dup.clear_query!
5
- end
6
-
7
- def clear_query!
8
- gsub!(/\s+/, ' ')
9
- strip!
10
- self
11
- end
12
-
13
- def nums_only
14
- scan(/\d/).join
15
- end
16
-
17
- def numeric?
18
- true if Float(self) rescue false
19
- end
20
-
21
- def to_bool
22
- %w[t true yes on 1].include? self
23
- end
24
-
25
- def sanitize(options = {})
26
- ActionController::Base.helpers.sanitize(self, options)
27
- end
28
-
29
- def nl2br
30
- dup.nl2br!
31
- end
32
-
33
- def nl2br!
34
- gsub!(/\r/, '')
35
- gsub!(/\n/, '<br>')
36
- self
37
- end
38
-
39
- def strip_leading_zeros
40
- dup.strip_leading_zeros!
41
- end
42
-
43
- def strip_leading_zeros!
44
- gsub!(/^0+/, '')
45
- self
46
- end
47
-
48
- def try_to_integer
49
- Integer( try_to_big_decimal ) rescue self
50
- end
51
-
52
- def try_to_big_decimal
53
- gsub!(/\s/, '')
54
- begin
55
- Float(self)
56
- rescue
57
- return self
58
- end
59
- BigDecimal(self)
60
- end
61
-
62
- end
data/lib/dry/errors.rb DELETED
@@ -1,77 +0,0 @@
1
- module Dry
2
- class Errors
3
-
4
- attr_reader :messages
5
-
6
- def initialize(messages = {})
7
- @messages = messages
8
- end
9
-
10
-
11
- def add(key, message)
12
- keys = key.to_s.split('.').map!(&:to_sym)
13
- old = messages.dig(*keys[0...-1]) rescue {}
14
- old = {} unless old.is_a?(Hash)
15
- new = keys[0...-1].inject(messages) { |h, k| h[k] ||= {} rescue h = {}; h[k] = {} }
16
- new[keys.last] = [] unless new.is_a?(Array)
17
- new[keys.last] << message
18
- new.merge!(old)
19
- end
20
-
21
-
22
- def merge!(error, parent_key = nil)
23
- hash_to_dots(error.messages, {}, parent_key).each do |key, messages|
24
- messages.each { |message| add(key, message) }
25
- end
26
- messages
27
- end
28
-
29
-
30
- def any?
31
- messages.any?
32
- end
33
-
34
-
35
- def has_key?(key)
36
- keys = key.to_s.split('.').map!(&:to_sym)
37
- keys.size == 1 ? messages[keys.first].present? : (messages.dig(*keys[0...-1])[keys.last].present? rescue false)
38
- end
39
-
40
-
41
- def first_message
42
- fetch_messages(messages.values.first).first
43
- end
44
-
45
-
46
- def clone
47
- self.class.new(messages.clone)
48
- end
49
-
50
-
51
- private
52
-
53
-
54
- def hash_to_dots(hash, results = {}, start_key = '')
55
- hash.each do |key, value|
56
- key = key.to_s
57
- key_value = start_key.present? ? sprintf('%s.%s', start_key, key) : key
58
- if value.is_a?(Hash)
59
- results.merge!(hash_to_dots(value, results, key_value))
60
- else
61
- results[key_value] = value
62
- end
63
- end
64
- results
65
- end
66
-
67
-
68
- def fetch_messages(value)
69
- if value.is_a?(Hash)
70
- fetch_messages(value.values.first)
71
- else
72
- value
73
- end
74
- end
75
-
76
- end
77
- end