pg_rails 7.0.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 +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +73 -0
  4. data/Rakefile +36 -0
  5. data/app/assets/javascripts/pg_rails/asociacion_creable.js +85 -0
  6. data/app/assets/javascripts/pg_rails/best_in_place_datepicker.js +58 -0
  7. data/app/assets/javascripts/pg_rails/librerias.js +13 -0
  8. data/app/assets/javascripts/pg_rails/librerias_b3.js +14 -0
  9. data/app/assets/javascripts/pg_rails/validaciones.js +44 -0
  10. data/app/assets/javascripts/pg_rails.js +318 -0
  11. data/app/assets/stylesheets/pg_rails/librerias.scss +5 -0
  12. data/app/assets/stylesheets/pg_rails/pg_chosen.scss +29 -0
  13. data/app/assets/stylesheets/pg_rails/pg_rails.scss +199 -0
  14. data/app/assets/stylesheets/pg_rails_b3.scss +10 -0
  15. data/app/assets/stylesheets/pg_rails_b4.scss +12 -0
  16. data/app/assets/stylesheets/pg_rails_b5.scss +1 -0
  17. data/app/controllers/pg_rails/application_controller.rb +316 -0
  18. data/app/controllers/pg_rails/editar_en_lugar_controller.rb +24 -0
  19. data/app/decorators/pg_rails/base_decorator.rb +120 -0
  20. data/app/helpers/pg_rails/editar_en_lugar_helper.rb +106 -0
  21. data/app/helpers/pg_rails/form_helper.rb +25 -0
  22. data/app/helpers/pg_rails/postgres_helper.rb +15 -0
  23. data/app/helpers/pg_rails/print_helper.rb +176 -0
  24. data/app/inputs/pg_rails/asociacion_creable_input.rb +72 -0
  25. data/app/inputs/pg_rails/fecha_input.rb +20 -0
  26. data/app/inputs/pg_rails/selects_dependientes_input.rb +9 -0
  27. data/app/lib/pg_form_builder.rb +31 -0
  28. data/app/lib/pg_rails/filtros_builder.rb +338 -0
  29. data/app/models/pg_rails/application_record.rb +51 -0
  30. data/app/policies/pg_rails/application_policy.rb +104 -0
  31. data/app/views/application/_abrir_modal.js.erb +14 -0
  32. data/app/views/application/_actualizar_smart_listing.html.slim +3 -0
  33. data/app/views/application/_cerrar_modal.js.erb +8 -0
  34. data/app/views/application/_modal_ajax_form.js.erb +7 -0
  35. data/config/brakeman.ignore +42 -0
  36. data/config/locales/es.yml +17 -0
  37. data/config/routes.rb +3 -0
  38. data/config/spring.rb +1 -0
  39. data/lib/pg_rails/configuracion.rb +24 -0
  40. data/lib/pg_rails/core_ext.rb +17 -0
  41. data/lib/pg_rails/engine.rb +42 -0
  42. data/lib/pg_rails/simple_form/initializer.rb +583 -0
  43. data/lib/pg_rails/utils/logueador.rb +39 -0
  44. data/lib/pg_rails/version.rb +5 -0
  45. data/lib/pg_rails.rb +23 -0
  46. data/lib/tasks/auto_anotar_modelos.rake +34 -0
  47. data/lib/tasks/pg_rails_tasks.rake +5 -0
  48. metadata +89 -0
@@ -0,0 +1,338 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PgRails
4
+ class FiltrosBuilder
5
+ include ActionView::Helpers
6
+ include ActionView::Context
7
+ include PostgresHelper
8
+ attr_accessor :controller
9
+
10
+ SUFIJOS = %w[desde hasta incluye es_igual_a].freeze
11
+
12
+ def initialize(controller, clase_modelo, campos)
13
+ @clase_modelo = clase_modelo
14
+ @campos = campos
15
+ @controller = controller
16
+ @filtros = {}
17
+ @campos.each { |campo| @filtros[campo] = {} }
18
+ end
19
+
20
+ def opciones(campo, opciones)
21
+ # TODO: mergear
22
+ @filtros[campo] = opciones
23
+ end
24
+
25
+ # querys customizadas por campo
26
+ def query(campo, &block)
27
+ @filtros[campo] = {} if @filtros[campo].nil?
28
+ @filtros[campo][:query] = block
29
+ end
30
+
31
+ def scope_asociacion(campo, &block)
32
+ @filtros[campo] = {} if @filtros[campo].nil?
33
+ @filtros[campo][:scope_asociacion] = block
34
+ end
35
+
36
+ def algun_filtro_presente?
37
+ @campos.any? { |campo| parametros_controller[campo].present? }
38
+ end
39
+
40
+ def filtrar(query, parametros = nil)
41
+ parametros = parametros_controller if parametros.nil?
42
+
43
+ # Filtro soft deleted, y sea con paranoia o con discard
44
+ query = query.without_deleted if query.respond_to?(:without_deleted)
45
+ query = query.kept if query.respond_to?(:kept)
46
+
47
+ @filtros.each do |campo, _opciones|
48
+ next unless parametros[campo].present?
49
+
50
+ if @filtros[campo.to_sym].present? && @filtros[campo.to_sym][:query].present?
51
+ query = @filtros[campo.to_sym][:query].call(query, parametros[campo])
52
+ elsif tipo(campo) == :enumerized
53
+ columna = @clase_modelo.columns.find { |c| c.name == campo.to_s }
54
+ if columna.array
55
+ query = query.where("? = any(#{@clase_modelo.table_name}.#{campo})", parametros[campo])
56
+ else
57
+ query = query.where("#{@clase_modelo.table_name}.#{campo} = ?", parametros[campo])
58
+ end
59
+ elsif tipo(campo).in?(%i[integer float decimal])
60
+ campo_a_comparar = "#{@clase_modelo.table_name}.#{sin_sufijo(campo)}"
61
+ query = query.where("#{campo_a_comparar} #{comparador(campo)} ?", parametros[campo])
62
+ elsif tipo(campo) == :asociacion
63
+ nombre_campo = sin_sufijo(campo)
64
+ suf = extraer_sufijo(campo)
65
+ asociacion = obtener_asociacion(nombre_campo)
66
+ if asociacion.instance_of?(ActiveRecord::Reflection::HasAndBelongsToManyReflection)
67
+ array = parametros[campo].instance_of?(Array) ? parametros[campo].join(',') : parametros[campo]
68
+ query = query.joins(nombre_campo.to_sym).group("#{@clase_modelo.table_name}.id")
69
+ .having("ARRAY_AGG(#{asociacion.join_table}.#{asociacion.association_foreign_key}) #{comparador_array(suf)} ARRAY[#{array}]::bigint[]")
70
+ elsif asociacion.instance_of?(ActiveRecord::Reflection::BelongsToReflection)
71
+ query = query.where("#{@clase_modelo.table_name}.#{campo}_id = ?", parametros[campo])
72
+ else
73
+ raise 'filtro de asociacion no soportado'
74
+ end
75
+ elsif tipo(campo).in?(%i[string text])
76
+ match_vector = parametros[campo].split.map { |a| "#{a}:*" }.join(' & ')
77
+ match_like = "%#{parametros[campo]}%"
78
+ campo_tabla = "#{@clase_modelo.table_name}.#{campo}"
79
+ condicion = "to_tsvector(coalesce(unaccent(#{campo_tabla}), '')) @@ to_tsquery( unaccent(?) )"
80
+ condicion += " OR unaccent(CONCAT(#{campo_tabla})) ILIKE unaccent(?)"
81
+ query = query.where(condicion, I18n.transliterate(match_vector).to_s,
82
+ I18n.transliterate(match_like).to_s)
83
+ elsif tipo(campo) == :boolean
84
+ if campo.to_s == 'discarded'
85
+ # Si el nombre del campo es 'discarded' entonces no es un campo
86
+ # real sino filtro booleano por presencia de discarded_at
87
+ case parametros[campo]
88
+ when 'si'
89
+ query = query.unscope(where: :discarded_at).where("#{@clase_modelo.table_name}.discarded_at IS NOT NULL")
90
+ when 'no'
91
+ query = query.unscope(where: :discarded_at).where("#{@clase_modelo.table_name}.discarded_at IS NULL")
92
+ end
93
+ else
94
+ # Si no simplemente hago la query por booleano
95
+ query = query.where("#{@clase_modelo.table_name}.#{campo} = ?", parametros[campo] == 'si')
96
+ end
97
+ elsif tipo(campo) == :date || tipo(campo) == :datetime
98
+ begin
99
+ fecha = Date.parse(parametros[campo])
100
+ fecha = fecha + 1.day - 1.second if tipo(campo) == :datetime && comparador(campo) == '<'
101
+ campo_a_comparar = "#{@clase_modelo.table_name}.#{sin_sufijo(campo)}"
102
+ query = query.where("#{campo_a_comparar} #{comparador(campo)} ?", fecha)
103
+ rescue ArgumentError
104
+ end
105
+ end
106
+ end
107
+ query
108
+ end
109
+
110
+ def tipo(campo)
111
+ nombre_campo = sin_sufijo(campo)
112
+ if @filtros[nombre_campo.to_sym].present? && @filtros[nombre_campo.to_sym][:tipo].present?
113
+ @filtros[nombre_campo.to_sym][:tipo]
114
+ elsif @clase_modelo.respond_to?(:enumerized_attributes) && @clase_modelo.enumerized_attributes[nombre_campo.to_s].present?
115
+ :enumerized
116
+ elsif @clase_modelo.reflect_on_all_associations.find do |a|
117
+ a.name == nombre_campo.to_sym
118
+ end.present?
119
+ :asociacion
120
+ else
121
+ columna = @clase_modelo.columns.find { |c| c.name == nombre_campo.to_s }
122
+ if columna.nil?
123
+ return :date if campo.match(/fecha/)
124
+
125
+ # Si el nombre del campo es 'discarded' entonces no es un campo
126
+ # real sino filtro booleano por presencia de discarded_at
127
+ return :boolean if campo.to_s == 'discarded'
128
+
129
+ Rails.logger.warn("no existe el campo: #{nombre_campo}")
130
+ return
131
+ end
132
+ columna.type
133
+ end
134
+ end
135
+
136
+ def comparador_array(sufijo)
137
+ case sufijo
138
+ when 'es_igual_a'
139
+ '='
140
+ else
141
+ # si es 'incluye'
142
+ # o si no tiene sufijo que por defecto se use el includes
143
+ '@>'
144
+ end
145
+ end
146
+
147
+ def comparador(campo)
148
+ if campo.to_s.ends_with?('_desde')
149
+ '>='
150
+ elsif campo.to_s.ends_with?('_hasta')
151
+ '<='
152
+ else
153
+ '='
154
+ end
155
+ end
156
+
157
+ def extraer_sufijo(campo)
158
+ SUFIJOS.each do |sufijo|
159
+ return sufijo if campo.to_s.ends_with?("_#{sufijo}")
160
+ end
161
+ nil
162
+ end
163
+
164
+ def sin_sufijo(campo)
165
+ ret = campo.to_s.dup
166
+ SUFIJOS.each do |sufijo|
167
+ ret.gsub!(/_#{sufijo}$/, '')
168
+ end
169
+ ret
170
+ end
171
+
172
+ def placeholder_campo(campo)
173
+ suf = extraer_sufijo(campo)
174
+ if suf.present?
175
+ "#{@clase_modelo.human_attribute_name(sin_sufijo(campo))} #{suf}"
176
+ else
177
+ @clase_modelo.human_attribute_name(campo)
178
+ end
179
+ end
180
+
181
+ def filtros_html(options = {})
182
+ res = ''
183
+ @filtros.each do |campo, opciones|
184
+ if opciones[:oculto] ||
185
+ (options[:except].present? && options[:except].include?(campo.to_sym)) ||
186
+ (options[:only].present? && !options[:only].include?(campo.to_sym))
187
+ next
188
+ end
189
+
190
+ res += case tipo(campo)
191
+ when :select_custom
192
+ filtro_select_custom(campo, placeholder_campo(campo))
193
+ when :enumerized
194
+ filtro_select(campo, placeholder_campo(campo))
195
+ when :asociacion
196
+ filtro_asociacion(campo, placeholder_campo(campo))
197
+ when :date, :datetime
198
+ filtro_fecha(campo, placeholder_campo(campo))
199
+ when :boolean
200
+ filtro_boolean(campo, placeholder_campo(campo))
201
+ else
202
+ filtro_texto(campo, placeholder_campo(campo))
203
+ end
204
+ end
205
+ res += hidden_field_tag('order_by', parametros_controller['order_by'])
206
+ res += hidden_field_tag('order_direction', parametros_controller['order_direction'])
207
+ res.html_safe
208
+ end
209
+
210
+ def obtener_asociacion(campo)
211
+ nombre_campo = sin_sufijo(campo)
212
+ extraer_sufijo(campo)
213
+ asociacion = @clase_modelo.reflect_on_all_associations.find do |a|
214
+ a.name == nombre_campo.to_sym
215
+ end
216
+ raise 'no se encontró la asociacion' if asociacion.nil?
217
+
218
+ if asociacion.instance_of?(ActiveRecord::Reflection::ThroughReflection)
219
+ through_class = asociacion.through_reflection.class_name.constantize
220
+ asociacion_posta = through_class.reflect_on_all_associations.find do |a|
221
+ a.name == nombre_campo.to_sym
222
+ end
223
+ raise 'no se encontró la asociacion' if asociacion_posta.nil?
224
+
225
+ asociacion_posta
226
+ else
227
+ asociacion
228
+ end
229
+ end
230
+
231
+ def filtro_asociacion(campo, _placeholder = '')
232
+ asociacion = obtener_asociacion(campo)
233
+ multiple = asociacion.instance_of?(ActiveRecord::Reflection::HasAndBelongsToManyReflection)
234
+ nombre_clase = asociacion.options[:class_name]
235
+ nombre_clase = asociacion.name.to_s.camelize if nombre_clase.nil?
236
+ clase_asociacion = Object.const_get(nombre_clase)
237
+ scope = Pundit.policy_scope!(controller.send(PgRails.configuracion.current_user_method), clase_asociacion)
238
+
239
+ # Filtro soft deleted, y sea con paranoia o con discard
240
+ scope = scope.without_deleted if scope.respond_to?(:without_deleted)
241
+ scope = scope.kept if scope.respond_to?(:kept)
242
+
243
+ if @filtros[campo.to_sym][:scope_asociacion].present?
244
+ scope = @filtros[campo.to_sym][:scope_asociacion].call(scope)
245
+ end
246
+
247
+ map = scope.map { |o| [o.to_s, o.id] }
248
+
249
+ unless @filtros[campo.to_sym].present? && @filtros[campo.to_sym][:include_blank] == false
250
+ map.unshift ["Seleccionar #{@clase_modelo.human_attribute_name(campo.to_sym).downcase}",
251
+ nil]
252
+ end
253
+
254
+ default = parametros_controller[campo].nil? ? nil : parametros_controller[campo]
255
+ content_tag :div, class: 'col-auto' do
256
+ content_tag :div, class: 'filter' do
257
+ if multiple
258
+ select_tag campo, options_for_select(map, default), multiple: true,
259
+ class: 'form-select form-select-sm selectize pg-input-lg'
260
+ else
261
+ select_tag campo, options_for_select(map, default),
262
+ class: 'form-select form-select-sm chosen-select pg-input-lg'
263
+ end
264
+ end
265
+ end
266
+ end
267
+
268
+ def filtro_select(campo, placeholder = '')
269
+ map = @clase_modelo.send(campo).values.map do |key|
270
+ [I18n.t("#{@clase_modelo.to_s.underscore}.#{campo}.#{key}", default: key.humanize),
271
+ key.value]
272
+ end
273
+ unless @filtros[campo.to_sym].present? && @filtros[campo.to_sym][:include_blank] == false
274
+ map.unshift ["Seleccionar #{placeholder.downcase}",
275
+ nil]
276
+ end
277
+ default = parametros_controller[campo].nil? ? nil : parametros_controller[campo]
278
+ content_tag :div, class: 'col-auto' do
279
+ content_tag :div, class: 'filter' do
280
+ select_tag campo, options_for_select(map, default), class: 'form-select form-select-sm pg-input-lg'
281
+ end
282
+ end
283
+ end
284
+
285
+ def filtro_select_custom(campo, placeholder = '')
286
+ map = @filtros[campo.to_sym][:opciones]
287
+ unless @filtros[campo.to_sym].present? && @filtros[campo.to_sym][:include_blank] == false
288
+ map.unshift ["Seleccionar #{placeholder.downcase}",
289
+ nil]
290
+ end
291
+ default = parametros_controller[campo].nil? ? nil : parametros_controller[campo]
292
+ content_tag :div, class: 'col-auto' do
293
+ content_tag :div, class: 'filter' do
294
+ select_tag campo, options_for_select(map, default), class: 'form-select form-select-sm pg-input-lg'
295
+ end
296
+ end
297
+ end
298
+
299
+ def filtro_texto(campo, placeholder = '')
300
+ content_tag :div, class: 'col-auto' do
301
+ content_tag :div, class: 'filter' do
302
+ text_field_tag(
303
+ campo, parametros_controller[campo], class: 'form-control form-control-sm allow-enter-submit', placeholder: placeholder, autocomplete: 'off'
304
+ )
305
+ end
306
+ end
307
+ end
308
+
309
+ def filtro_boolean(campo, placeholder = '')
310
+ map = [%w[Si si], %w[No no]]
311
+ unless @filtros[campo.to_sym].present? && @filtros[campo.to_sym][:include_blank] == false
312
+ map.unshift ["¿#{placeholder.titleize}?",
313
+ nil]
314
+ end
315
+ default = parametros_controller[campo].nil? ? nil : parametros_controller[campo]
316
+ content_tag :div, class: 'col-auto' do
317
+ content_tag :div, class: 'filter' do
318
+ select_tag campo, options_for_select(map, default), class: 'form-select form-select-sm pg-input-lg'
319
+ end
320
+ end
321
+ end
322
+
323
+ def filtro_fecha(campo, placeholder = '')
324
+ content_tag :div, class: 'col-auto' do
325
+ content_tag :div, class: 'filter' do
326
+ label_tag(nil, placeholder, class: 'text-muted') + \
327
+ date_field_tag(
328
+ campo, parametros_controller[campo], class: 'form-control form-control-sm d-inline-block w-auto ms-1', placeholder: placeholder, autocomplete: 'off'
329
+ )
330
+ end
331
+ end
332
+ end
333
+
334
+ def parametros_controller
335
+ params
336
+ end
337
+ end
338
+ end
@@ -0,0 +1,51 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PgRails
4
+ class ApplicationRecord < ActiveRecord::Base
5
+ extend Enumerize
6
+ include PrintHelper
7
+ include PostgresHelper
8
+
9
+ self.abstract_class = true
10
+
11
+ attr_accessor :current_user
12
+
13
+ before_create :setear_creado_y_actualizado_por
14
+ before_update :setear_actualizado_por
15
+
16
+ def self.nombre_plural
17
+ model_name.human(count: 2)
18
+ end
19
+
20
+ def self.nombre_singular
21
+ model_name.human(count: 1)
22
+ end
23
+
24
+ def to_s
25
+ %i[nombre name].each do |campo|
26
+ return send(campo) if try(campo).present?
27
+ end
28
+ if id.present?
29
+ "#{self.class.nombre_singular} ##{id}"
30
+ else
31
+ super
32
+ end
33
+ end
34
+
35
+ private
36
+
37
+ def setear_creado_y_actualizado_por
38
+ setear_si_existe :creado_por, current_user
39
+ setear_si_existe :actualizado_por, current_user
40
+ end
41
+
42
+ def setear_actualizado_por
43
+ setear_si_existe :actualizado_por, current_user
44
+ end
45
+
46
+ def setear_si_existe(campo, valor)
47
+ metodo = "#{campo}="
48
+ send(metodo, valor) if respond_to?(metodo) && valor.present?
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,104 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PgRails
4
+ class ApplicationPolicy
5
+ attr_reader :user, :record
6
+
7
+ def initialize(user, record)
8
+ @user = user
9
+ @record = record
10
+ end
11
+
12
+ def editar_en_lugar?
13
+ puede_editar?
14
+ end
15
+
16
+ def index?
17
+ raise "esta policy se llama con la clase modelo y no con #{record.class}" unless record.class
18
+
19
+ acceso_total? || Pundit.policy_scope!(user, record).any?
20
+ end
21
+
22
+ def show?
23
+ # scope.where(id: record.id).exists?
24
+ acceso_total?
25
+ end
26
+
27
+ def create?
28
+ puede_crear?
29
+ end
30
+
31
+ def new?
32
+ create?
33
+ end
34
+
35
+ def update?
36
+ puede_editar? && !objeto_borrado?
37
+ end
38
+
39
+ def edit?
40
+ update?
41
+ end
42
+
43
+ def destroy?
44
+ puede_borrar? && !objeto_borrado?
45
+ end
46
+
47
+ def scope
48
+ Pundit.policy_scope!(user, record.class)
49
+ end
50
+
51
+ class Scope
52
+ attr_reader :user, :scope
53
+
54
+ def initialize(user, scope)
55
+ @user = user
56
+ @scope = scope
57
+ end
58
+
59
+ def resolve
60
+ if policy.acceso_total?
61
+ scope.all
62
+ else
63
+ scope.none
64
+ end
65
+ end
66
+
67
+ def policy
68
+ raise "el scope debe ser una clase modelo y no #{scope.class}" unless scope.class
69
+
70
+ Pundit.policy!(user, scope)
71
+ end
72
+ end
73
+
74
+ def puede_editar?
75
+ acceso_total?
76
+ end
77
+
78
+ def puede_crear?
79
+ acceso_total?
80
+ end
81
+
82
+ def puede_borrar?
83
+ acceso_total?
84
+ end
85
+
86
+ def export?
87
+ acceso_total?
88
+ end
89
+
90
+ def acceso_total?
91
+ user.admin?
92
+ end
93
+
94
+ def objeto_borrado?
95
+ if record.respond_to?(:deleted?)
96
+ record.deleted?
97
+ elsif record.respond_to?(:discarded?)
98
+ record.discarded?
99
+ else
100
+ false
101
+ end
102
+ end
103
+ end
104
+ end
@@ -0,0 +1,14 @@
1
+ $(function() {
2
+ var modal = $('<%= j render contenido %>').modal();
3
+
4
+ <% if defined? extra_js %>
5
+ <% [extra_js].flatten.each do |partial| %>
6
+ <%= render partial: partial %>
7
+ <% end %>
8
+ <% end %>
9
+ $(modal).on('hidden.bs.modal', function () {
10
+ $(this).data('bs.modal', null);
11
+ $(this).remove();
12
+ });
13
+ PgRails.bindear('.modal')
14
+ });
@@ -0,0 +1,3 @@
1
+ = smart_listing_update(smart_listing_key)
2
+
3
+ | PgRails.bindear('##{smart_listing_key}');
@@ -0,0 +1,8 @@
1
+ $(function() {
2
+ $('.modal').modal('hide');
3
+ <% if @saved %>
4
+ $('.smart-listing').smart_listing().reload();
5
+ <% else %>
6
+ <%= render partial: 'abrir_modal', locals: { contenido: contenido, extra_js: extra_js } %>
7
+ <% end %>
8
+ });
@@ -0,0 +1,7 @@
1
+ var options = {
2
+ dataType: 'script',
3
+ beforeSubmit: function(arr, form, options) {
4
+ return form.valid();
5
+ }
6
+ }
7
+ $('.modal').find('form').ajaxForm(options);
@@ -0,0 +1,42 @@
1
+ {
2
+ "ignored_warnings": [
3
+ {
4
+ "warning_type": "Remote Code Execution",
5
+ "warning_code": 24,
6
+ "fingerprint": "8128e4baa0b47430684e599d2c3944b5446ad95caa6fbd263b7fa984a91842cd",
7
+ "check_name": "UnsafeReflection",
8
+ "message": "Unsafe reflection method `const_get` called with parameter value",
9
+ "file": "app/controllers/pg_rails/editar_en_lugar_controller.rb",
10
+ "line": 7,
11
+ "link": "https://brakemanscanner.org/docs/warning_types/remote_code_execution/",
12
+ "code": "Kernel.const_get(params.keys[1])",
13
+ "render_path": null,
14
+ "location": {
15
+ "type": "method",
16
+ "class": "PgRails::EditarEnLugarController",
17
+ "method": "actualizar"
18
+ },
19
+ "user_input": "params.keys[1]",
20
+ "confidence": "High",
21
+ "note": ""
22
+ },
23
+ {
24
+ "warning_type": "Cross-Site Scripting",
25
+ "warning_code": 106,
26
+ "fingerprint": "c8adc1c0caf2c9251d1d8de588fb949070212d0eed5e1580aee88bab2287b772",
27
+ "check_name": "SanitizeMethods",
28
+ "message": "loofah gem 2.12.0 is vulnerable (CVE-2018-8048). Upgrade to 2.2.1",
29
+ "file": "Gemfile.lock",
30
+ "line": 201,
31
+ "link": "https://github.com/flavorjones/loofah/issues/144",
32
+ "code": null,
33
+ "render_path": null,
34
+ "location": null,
35
+ "user_input": null,
36
+ "confidence": "Medium",
37
+ "note": ""
38
+ }
39
+ ],
40
+ "updated": "2021-09-09 15:02:20 -0300",
41
+ "brakeman_version": "4.10.0"
42
+ }
@@ -0,0 +1,17 @@
1
+ es:
2
+ created_at: Fecha de creación
3
+ updated_at: Fecha de actualización
4
+ deleted_at: Fecha de borrado
5
+ discarded_at: Fecha de borrado
6
+ actualizado_por: Actualizado por
7
+ creado_por: Creado por
8
+ ancestry:
9
+ exclude_self: No puede ser hijx de si mismx
10
+ simple_form:
11
+ # labels:
12
+ # user:
13
+ # username: 'User name'
14
+ # password: 'Password'
15
+ # hints:
16
+ error_notification:
17
+ default_message: "hubo algunos errores:"
data/config/routes.rb ADDED
@@ -0,0 +1,3 @@
1
+ PgRails::Engine.routes.draw do
2
+ put 'editar_en_lugar/:id', to: 'editar_en_lugar#actualizar', as: :editar_en_lugar
3
+ end
data/config/spring.rb ADDED
@@ -0,0 +1 @@
1
+ Spring.application_root = 'spec/dummy'
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PgRails
4
+ class Configuracion
5
+ attr_accessor :sistema_iconos, :clase_botones_chicos, :boton_destroy, :boton_edit,
6
+ :boton_show, :boton_light, :icono_destroy, :icono_edit, :icono_show, :boton_export, :bootstrap_version,
7
+ :current_user_method
8
+
9
+ def initialize
10
+ @sistema_iconos = 'bi'
11
+ @clase_botones_chicos = 'btn-sm'
12
+ @boton_destroy = 'light'
13
+ @boton_export = 'warning'
14
+ @boton_edit = 'light'
15
+ @boton_show = 'light'
16
+ @boton_light = 'light'
17
+ @icono_destroy = 'trash-fill'
18
+ @icono_edit = 'pencil'
19
+ @icono_show = 'eye-fill'
20
+ @bootstrap_version = 5
21
+ @current_user_method = :current_user
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ # require 'activesupport/time'
4
+ module ActiveSupport
5
+ class TimeWithZone
6
+ def to_s(format = :default)
7
+ if format == :db
8
+ utc.to_s(format)
9
+ elsif formatter = ::Time::DATE_FORMATS[format] # rubocop:disable Lint/AssignmentInCondition
10
+ formatter.respond_to?(:call) ? formatter.call(self).to_s : strftime(formatter)
11
+ else
12
+ # "#{time.strftime("%Y-%m-%d %H:%M:%S")} #{formatted_offset(false, 'UTC')}" # mimicking Ruby Time#to_s format
13
+ time.strftime('%d/%m/%Y %H:%M')
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ # unless Rails.env.production?
4
+ # # require 'byebug'
5
+ # require 'factory_bot_rails'
6
+ # end
7
+
8
+ # require 'font-awesome-rails'
9
+ # require 'nested_form'
10
+ # require 'audited'
11
+ # # require 'best_in_place'
12
+ # # require 'bootstrap'
13
+ # # require 'bootstrap-datepicker-rails'
14
+ # require 'breadcrumbs_on_rails'
15
+ # require 'caxlsx_rails'
16
+ # require 'devise'
17
+ # require 'devise-i18n'
18
+ # require 'devise/orm/active_record'
19
+ # require 'draper'
20
+ # require 'enumerize'
21
+ # # require 'jquery-rails'
22
+ # require 'pundit'
23
+ # # require 'rails-assets-chosen'
24
+ # require 'rails-i18n'
25
+ # # require 'rollbar'
26
+ # # require 'selectize-rails'
27
+ # require 'simple_form'
28
+ # require 'slim'
29
+ # # require 'smart_listing'
30
+ # require 'kaminari'
31
+ # require 'kaminari-i18n'
32
+
33
+ require 'pg_rails/utils/logueador'
34
+
35
+ module PgRails
36
+ class Engine < ::Rails::Engine
37
+ isolate_namespace PgRails
38
+
39
+ config.i18n.default_locale = :es
40
+ config.time_zone = 'America/Argentina/Buenos_Aires'
41
+ end
42
+ end