base_editing_bootstrap 1.11.0 → 1.13.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3a94db145cbc0c8225a28489ba2c163a53d576e6baae96e294fc3b9d1db7e606
4
- data.tar.gz: 5e7f937da0131bb04457475ccaf2885a524faf002ec4917200957e6481bdccf2
3
+ metadata.gz: 03c295a72d7902af261c7c01405cc45a7b81d243c846f60c1974f4e07e5e648e
4
+ data.tar.gz: 5281b24d0df35c81db386217c763e266bf29affa07ca33c34632527981f5be5b
5
5
  SHA512:
6
- metadata.gz: f3f4e4df8738595c80519a96149dddced30cbb21cbffb3b606cc3d7f90c30ba7c1eff81d00fcaf763759be06d738a906c4d37af7ba67d16668e3bf8b1537522b
7
- data.tar.gz: 7e2f175ed20a1cc3e80f5f23c3c66b9bc0fd7ebf32b6acecb1a7e06876a39c401e878c1318bf761c64b52ec65c597979a95c5e07c9196682f0bf5f561a4ffc61
6
+ metadata.gz: cdd4c188cef1aba14fadc79888e24fbdf3dafdbcc204ec933a1558ef5fbbed0255f36924c4e327c244e8176e777452077404a3c0c23b3ebeb1c869af62bf9ae3
7
+ data.tar.gz: 74c856a196196dd319d42446c474d5ba5449cefb2d01a7333d3e20bc2b4bcbb1273777b01363381e52a0fc8abbdd9bc9249a8cd5da4cd8dc60d2e470408994f3
data/CHANGELOG.md CHANGED
@@ -2,6 +2,40 @@
2
2
  All notable changes to this project will be documented in this file. See [conventional commits](https://www.conventionalcommits.org/) for commit guidelines.
3
3
 
4
4
  - - -
5
+ ## 1.13.0 - 2026-02-03
6
+ #### Features
7
+ - Form submit button inheritance value - (00b04b1) - Marino Bonetti
8
+ - Add customizability on model for form partial (#21) - (b7cead4) - Marino Bonetti
9
+ - Add BaseEditingBootstrap::Logging for form selection - (ecded89) - Marino Bonetti
10
+ #### Bug Fixes
11
+ - Warning escape - (1512271) - Marino Bonetti
12
+ - Correct submit text in case of not ActiveRecord - (6b658d4) - Marino Bonetti
13
+ #### Refactoring
14
+ - Replace `config_accessor` with `mattr_accessor` in BaseEditingBootstrap - (a4c3fb0) - Marino Bonetti
15
+ - BsLogging default tagging - (fbd4f2f) - Marino Bonetti
16
+ #### Miscellaneous Chores
17
+ - Add Ruby 4.0 as a valid version in matrix - (f32795e) - Marino Bonetti
18
+
19
+ - - -
20
+
21
+ ## 1.12.0 - 2025-12-05
22
+ #### Features
23
+ - Add Capacity of custom disable action column - (4910fc3) - Marino Bonetti
24
+ #### Bug Fixes
25
+ - Add ability to override new_button classes - (ba18b10) - Marino Bonetti
26
+ #### Documentation
27
+ - Update generator example - (445bf2f) - Marino Bonetti
28
+ - Update README with ransack sorting, distinct, and action column examples - (5b9728b) - Marino Bonetti
29
+ #### Tests
30
+ - Add option to define option_label_instance in shared example - (5e7628b) - Marino Bonetti
31
+ - Add Check for action columns - (001b0c9) - Marino Bonetti
32
+ #### Continuous Integration
33
+ - Add Rails 8.1 to Matrix - (455ffc6) - Marino Bonetti
34
+ #### Miscellaneous Chores
35
+ - Extend rails compatibility - (ef018b0) - Marino Bonetti
36
+
37
+ - - -
38
+
5
39
  ## 1.11.0 - 2025-09-15
6
40
  #### Bug Fixes
7
41
  - Simplify gem push command in cog.toml - (ab70061) - Marino Bonetti
data/README.md CHANGED
@@ -114,8 +114,19 @@ Utilizzo per modello base, in questo esempio prendiamo come modello Post come es
114
114
  ```ruby
115
115
  class PostsController < BaseEditingController
116
116
  ##
117
- # Set default sort order for ransack
117
+ # Configure default sort in the index query.
118
+ # Works like documented in https://activerecord-hackery.github.io/ransack/getting-started/sorting/#sorting-in-the-controller
118
119
  # self.default_sorts= ["id"]
120
+
121
+ ##
122
+ # Configure default distinct results in the index query.
123
+ # Works like documented in https://activerecord-hackery.github.io/ransack/going-further/other-notes/#problem-with-distinct-selects
124
+ # self.default_distinct=true
125
+
126
+ ##
127
+ # Display action column in the index table.
128
+ # self.display_action_column = true
129
+
119
130
  end
120
131
  ```
121
132
  - Aggiungere la rotta: `resources :posts`
@@ -186,6 +197,19 @@ Utilizzo per modello base, in questo esempio prendiamo come modello Post come es
186
197
  - default => base.html.erb
187
198
 
188
199
  **Form Field**
200
+ - CUSTOM => Nel modello, richiamare il metodo di classe per impostare il partial per lo specifico campo,
201
+ dal punto di vista del helper per ricercare il partial corretto avverrà poi il normale iter di ricerca
202
+ fra namespace di classe e namespace di controller per trovare il corretto partial:
203
+ ```ruby
204
+ class MyCustomModel < ApplicationRecord
205
+ include BaseEditingBootstrap::BaseModel
206
+ set_field_to_form_partial :title, :textarea
207
+ end
208
+ ```
209
+ E' anche disponibile un helper per testare la corretta configurazione:
210
+ ```ruby
211
+ it_behaves_like "a model with custom field_to_form_partial", :importo, :currency
212
+ ```
189
213
  - Integer => _integer.html.erb
190
214
  - Float => _decimal.html.erb
191
215
  - Decimal => _decimal.html.erb
@@ -219,8 +243,8 @@ Utilizzo per modello base, in questo esempio prendiamo come modello Post come es
219
243
  nested attraverso quanto elencato nella policy dell'oggetto padre.
220
244
  - Default/String => _base.html.erb
221
245
 
222
- In futuro si prevede di aggiungere automatismi per renderizzare senza
223
- l'intervento dell'utente dei campi.
246
+ In futuro si prevede di aggiungere automatismi per renderizzare senza
247
+ l'intervento dell'utente dei campi.
224
248
  - [OPTIONAL] Search Form:
225
249
  Per poter aggiungere una form di ricerca basta aggiungere alla policy
226
250
  del modello in questione i campi di ricerca che verranno poi utilizzati da ransack
@@ -252,10 +276,22 @@ Fai riferimento all'implementazione di esempio del dummy `Company->addresses`
252
276
 
253
277
  ### Translations
254
278
 
255
- Traduzioni disponibili:
279
+ #### Index buttons:
256
280
  Per i bottoni della index, è possibile eseguire l'override del testo presente nel bottone.
257
281
  Leggere la documentazione nel file `app/helpers/base_editing_helper.rb#translate_with_controller_scoped`
258
282
 
283
+ #### Per i bottoni delle form(Submit):
284
+ E' possibile tradurre il contenuto del bottone andando ad impostare la traduzione direttamente in yml.
285
+ ES:
286
+ Con la class inheritance così composta: Remote < Base < ApplicationRecord < ActiveRecord::Base
287
+ per il bottone dell'oggetto Remote avremo questa ricerca:
288
+ 1. en.helpers.submit.remote.create
289
+ 2. en.helpers.submit.base.create
290
+ 3. en.helpers.submit.create
291
+
292
+ In caso di oggetto persistente verrà ricercata la chiave finale `update`
293
+
294
+
259
295
  ## Testing helpers
260
296
 
261
297
  ### Requirements(installed with generators)
@@ -19,15 +19,20 @@ class BaseEditingController < RestrictedAreaController
19
19
  # Works like documented in https://activerecord-hackery.github.io/ransack/going-further/other-notes/#problem-with-distinct-selects
20
20
  class_attribute :default_distinct, default: true
21
21
 
22
+ ##
23
+ # Display action column in the index table.
24
+ class_attribute :display_action_column, default: true
25
+
22
26
  def index
23
- #se è già stato autorizzano non rieseguiamo, utile nel caso vogliamo sovrascrivere la logica di autorizzazione in inheritance
27
+ # se è già stato autorizzano non rieseguiamo, utile nel caso vogliamo sovrascrivere la logica di autorizzazione in inheritance
24
28
  authorize base_class unless pundit_policy_authorized?
25
29
 
26
30
  q = policy_scope(base_scope)
27
31
  @search_instance = search_class.new(q, current_user,
28
32
  params: params.permit(:page, :q => {}), # FIXME trovare modo per essere più "STRONG"
29
33
  sorts: default_sorts,
30
- distinct: default_distinct
34
+ distinct: default_distinct,
35
+ display_action_column: display_action_column
31
36
  )
32
37
  @search_instance = yield(@search_instance) if block_given?
33
38
  end
@@ -36,7 +41,7 @@ class BaseEditingController < RestrictedAreaController
36
41
  @object = base_class.new
37
42
  @object = yield(@object) if block_given?
38
43
 
39
- #se è già stato autorizzano non rieseguiamo, utile nel caso vogliamo sovrascrivere la logica di autorizzazione in inheritance
44
+ # se è già stato autorizzano non rieseguiamo, utile nel caso vogliamo sovrascrivere la logica di autorizzazione in inheritance
40
45
  authorize @object unless pundit_policy_authorized?
41
46
 
42
47
  respond_to do |format|
@@ -67,7 +72,7 @@ class BaseEditingController < RestrictedAreaController
67
72
  def create
68
73
  @object = base_class.new(permitted_attributes)
69
74
  @object = yield(@object) if block_given?
70
- #se è già stato autorizzano non rieseguiamo, utile nel caso vogliamo sovrascrivere la logica di autorizzazione in inheritance
75
+ # se è già stato autorizzano non rieseguiamo, utile nel caso vogliamo sovrascrivere la logica di autorizzazione in inheritance
71
76
  authorize @object unless pundit_policy_authorized?
72
77
 
73
78
  respond_to do |format|
@@ -129,7 +134,7 @@ class BaseEditingController < RestrictedAreaController
129
134
  def load_object
130
135
  @object = base_class.find(params[:id])
131
136
 
132
- #se è già stato autorizzano non rieseguiamo, utile nel caso vogliamo sovrascrivere la logica di autorizzazione in inheritance
137
+ # se è già stato autorizzano non rieseguiamo, utile nel caso vogliamo sovrascrivere la logica di autorizzazione in inheritance
133
138
  authorize @object unless pundit_policy_authorized?
134
139
  logger.debug { "Oggetto #{@object.inspect}" }
135
140
  end
@@ -4,6 +4,7 @@ module Utilities
4
4
  include EnumHelper
5
5
  include IconHelper
6
6
  include Pundit::Authorization
7
+ include BaseEditingBootstrap::Logging
7
8
  ##
8
9
  # Metodo su cui eseguire override per i campi specifici rispetto all'oggetto gestito dal controller
9
10
  # @deprecated Utilizza form_print_field(form, field) senza sovrascriverlo
@@ -20,7 +21,9 @@ module Utilities
20
21
  # @param [Symbol] field
21
22
  def form_print_field(form, field)
22
23
  locals = {form:, field:}
23
- if form.object.class.respond_to?(:defined_enums) && form.object.class.defined_enums.key?(field.to_s)
24
+ if form.object.class.respond_to?(:field_to_form_partial) and (generic_field = form.object.class.field_to_form_partial(field))
25
+ type= :custom
26
+ elsif form.object.class.respond_to?(:defined_enums) && form.object.class.defined_enums.key?(field.to_s)
24
27
  type = :enum
25
28
  generic_field = "enum"
26
29
  elsif form.object.class.respond_to?(:reflect_on_association) &&
@@ -88,13 +91,12 @@ module Utilities
88
91
  "form_field",
89
92
  generic_field
90
93
  )
91
- Rails.logger.debug do
94
+ bs_logger.debug do
92
95
  <<~TEXT
93
- [BASE EDITING BOOTSTRAP]
94
- TYPE: #{type}
95
- GENERIC_FIELD: #{generic_field}
96
- TEMPLATE: #{template.short_identifier}
97
- LOCALS:#{locals}
96
+ TYPE: #{type}
97
+ GENERIC_FIELD: #{generic_field}
98
+ TEMPLATE: #{template.short_identifier}
99
+ LOCALS:#{locals}
98
100
  TEXT
99
101
  end
100
102
  template.render(self, locals)
@@ -49,8 +49,7 @@ module Utilities::PageHelper
49
49
  # @param [String] path
50
50
  # @param [Hash] options
51
51
  def new_button(path, options = {})
52
- options.merge!({class: 'btn btn-success btn-sm'})
53
- link_to icon("plus-lg", I18n.t(:new)), path, options
52
+ link_to icon("plus-lg", I18n.t(:new)), path, options.reverse_merge({class: 'btn btn-success btn-sm'})
54
53
  end
55
54
 
56
55
  # @param [BaseModel] obj instance
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Utilities::TemplateHelper
4
-
4
+ include BaseEditingBootstrap::Logging
5
5
  ##
6
6
  # Ricerca template con fallbacks.
7
7
  # In ordine, cerca di trovare il partial per l'oggetto(tramite il metodo to_partial_path) e il campo specifico.
@@ -30,21 +30,23 @@ module Utilities::TemplateHelper
30
30
  start_class = start_class.superclass
31
31
  end
32
32
 
33
- [
34
- # Precedenza modello e campo specifico
35
- ["Campo SPECIFICO + inheritance tra modelli", field, obj_base_paths],
36
- # cerco tramite nome modello semplice, con namespace della risorsa (cell_field,header_field,form_field) e nome del campo specifico
37
- ["Campo specifico con nome modello + inheritance controllers", "#{obj.model_name.element}/#{base_path}/#{field}", lookup_context.prefixes],
38
- # cerco struttura senza il livello del nome del modello
39
- ["Campo specifico senza nome modello + inheritance controllers", "#{base_path}/#{field}", lookup_context.prefixes],
40
- # Ricerca tramite campo generico e prefissi di contesto che contiene anche controller e namespace di controller
41
- ["Campo GENERICO + inheritance controllers", "#{base_path}/#{generic_field}", lookup_context.prefixes],
42
- ["Campo GENERICO + inheritance tra modelli", generic_field, obj_base_paths],
43
- ["Default BaseEditingController", "base_editing/#{base_path}/#{generic_field}", []],
44
- ].each do |desc,partial, prefixes|
45
- Rails.logger.debug { "[BASE EDITING BOOTSTRAP] #{desc} - partial:`#{partial}` in #{prefixes.inspect}" }
46
- if lookup_context.exists?(partial, prefixes, true)
47
- return lookup_context.find(partial, prefixes, true)
33
+ bs_logger.tagged(field) do
34
+ [
35
+ # Precedenza modello e campo specifico
36
+ ["Campo SPECIFICO + inheritance tra modelli", field, obj_base_paths],
37
+ # cerco tramite nome modello semplice, con namespace della risorsa (cell_field,header_field,form_field) e nome del campo specifico
38
+ ["Campo specifico con nome modello + inheritance controllers", "#{obj.model_name.element}/#{base_path}/#{field}", lookup_context.prefixes],
39
+ # cerco struttura senza il livello del nome del modello
40
+ ["Campo specifico senza nome modello + inheritance controllers", "#{base_path}/#{field}", lookup_context.prefixes],
41
+ # Ricerca tramite campo generico e prefissi di contesto che contiene anche controller e namespace di controller
42
+ ["Campo GENERICO + inheritance controllers", "#{base_path}/#{generic_field}", lookup_context.prefixes],
43
+ ["Campo GENERICO + inheritance tra modelli", generic_field, obj_base_paths],
44
+ ["Default BaseEditingController", "base_editing/#{base_path}/#{generic_field}", []],
45
+ ].each do |desc, partial, prefixes|
46
+ bs_logger.debug { "#{desc} - partial:`#{partial}` in #{prefixes.inspect}" }
47
+ if lookup_context.exists?(partial, prefixes, true)
48
+ return lookup_context.find(partial, prefixes, true)
49
+ end
48
50
  end
49
51
  end
50
52
  # fallback finale
@@ -1,10 +1,10 @@
1
- <table class="table table-head-fixed text-nowrap <%= dom_class(@search_instance.model_klass,:search_results) %>">
1
+ <table class="table table-head-fixed text-nowrap <%= dom_class(@search_instance.model_klass, :search_results) %>">
2
2
  <thead>
3
3
  <tr>
4
4
  <% @search_instance.search_result_fields.each do |srf| %>
5
5
  <%= render_header_cell_field(@search_instance, srf) %>
6
6
  <% end %>
7
- <th class="action_col"></th>
7
+ <%= content_tag :th, nil, class: "action_col" if @search_instance.display_action_column %>
8
8
  </tr>
9
9
  </thead>
10
10
  <tbody>
@@ -2,7 +2,9 @@
2
2
  <% @search_instance.search_result_fields.each do |srf| %>
3
3
  <%= render_cell_field(obj, srf) %>
4
4
  <% end %>
5
- <td>
6
- <%= render partial: "search_result_buttons", locals: {obj:} %>
7
- </td>
5
+ <% if @search_instance.display_action_column %>
6
+ <td class="action_col">
7
+ <%= render partial: "search_result_buttons", locals: {obj:} %>
8
+ </td>
9
+ <% end %>
8
10
  </tr>
@@ -29,7 +29,7 @@ Gem::Specification.new do |spec|
29
29
  end
30
30
  spec.files += Dir['spec/support/external_shared/*.rb']
31
31
 
32
- spec.add_dependency "rails", [">= 7.0", "< 8.1"]
32
+ spec.add_dependency "rails", [">= 7.0", "< 9.0"]
33
33
  # Policy
34
34
  spec.add_dependency "pundit", ["~> 2.3", ">= 2.3.1"]
35
35
  # Search
@@ -1 +1 @@
1
- 1.11.0
1
+ 1.13.0
@@ -11,6 +11,7 @@ module BaseEditingBootstrap
11
11
  :ransackable_associations,
12
12
  :ransackable_scopes, to: :@class
13
13
 
14
+ class_attribute :_field_to_form_partial
14
15
 
15
16
  ##
16
17
  # Label da utilizzare nelle option per quando si genera le select dei belongs to
@@ -44,6 +45,25 @@ module BaseEditingBootstrap
44
45
  Pundit.policy(BaseEditingBootstrap.authentication_model.new, self.new).permitted_scopes_for_ransack.map(&:to_s)
45
46
  end
46
47
  end
48
+
49
+ ##
50
+ # Questo metodo registra sulla classe la tuppla campo e partial per impostare il
51
+ # partial da utilizzare nel rendering
52
+ #
53
+ # E' presente anche un helper per i test:
54
+ #
55
+ # it_behaves_like "a model with custom field_to_form_partial", :importo, :currency
56
+ #
57
+ def set_field_to_form_partial(field, partial)
58
+ self._field_to_form_partial ||= {}
59
+ self._field_to_form_partial = self._field_to_form_partial.merge(field => partial)
60
+ end
61
+
62
+ def field_to_form_partial(field)
63
+ return nil unless self._field_to_form_partial
64
+ self._field_to_form_partial.fetch(field, nil)
65
+ end
66
+
47
67
  end
48
68
  end
49
69
  end
@@ -106,6 +106,22 @@ module BaseEditingBootstrap::Forms
106
106
  # di seguire realmente il link con il browser.
107
107
  def submit(value = nil, options = {})
108
108
  @template.content_tag(:div, class: "btn-group mr-1") do
109
+
110
+ if value.nil? && object.respond_to?(:model_name)
111
+ key = object.respond_to?(:persisted?) ? (object.persisted? ? :update : :create) : :submit
112
+ defaults = []
113
+ tmp = object.class
114
+ while tmp != ::ActiveRecord::Base && tmp.respond_to?(:model_name)
115
+ defaults << :"helpers.submit.#{tmp.model_name.i18n_key}.#{key}"
116
+ tmp = tmp.superclass
117
+ end
118
+ defaults << :"helpers.submit.#{key}"
119
+ defaults << "_NOT_FOUND_TRANSLATION_"
120
+
121
+ value = I18n.translate(defaults.shift, model: object.model_name.human, default: defaults)
122
+ value = nil if value == "_NOT_FOUND_TRANSLATION_"
123
+ end
124
+
109
125
  super(value, options.reverse_merge(class: "btn btn-primary")) +
110
126
  @template.link_to(object.class.human_attribute_name(:_submit_undo, default: :undo),
111
127
  @template.index_custom_polymorphic_path(object.class),
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BaseEditingBootstrap
4
+ module Logging
5
+ def bs_logger
6
+ @logger ||= begin
7
+ config_logger = BaseEditingBootstrap.logger
8
+ config_logger = config_logger || (defined?(Rails) ? Rails.logger : Logger.new($stdout))
9
+ ActiveSupport::TaggedLogging.new(config_logger).tagged("BASE EDITING BOOTSTRAP")
10
+ end
11
+ end
12
+
13
+ end
14
+ end
@@ -7,18 +7,20 @@ module BaseEditingBootstrap::Searches
7
7
  include ActiveModel::Naming
8
8
  include ActiveModel::Conversion
9
9
 
10
- attr_reader :model_klass, :user, :params, :scope, :sorts, :distinct
10
+ attr_reader :model_klass, :user, :params, :scope, :sorts, :distinct, :display_action_column
11
11
 
12
12
  # @param [User] user
13
13
  # @param [ActiveRecord::Associations::CollectionProxy] scope
14
14
  # @param [Array<String (frozen)>] sort
15
- def initialize(scope, user, params: {page: nil}, sorts: ["id"], distinct: true)
15
+ # @param [TrueClass,FalseClass] display_action_column => visualizzare o meno la colonna delle azioni
16
+ def initialize(scope, user, params: {page: nil}, sorts: ["id"], distinct: true, display_action_column: true)
16
17
  @model_klass = scope.klass
17
18
  @user = user
18
19
  @scope = scope
19
20
  @params = params
20
21
  @sorts = sorts
21
22
  @distinct = distinct
23
+ @display_action_column = display_action_column
22
24
  end
23
25
 
24
26
  ##
@@ -16,29 +16,31 @@ loader.ignore("#{__dir__}/generators")
16
16
  loader.setup
17
17
 
18
18
  module BaseEditingBootstrap
19
- include ActiveSupport::Configurable
19
+ def self.configure
20
+ yield self
21
+ end
20
22
 
21
23
  ##
22
24
  # Controller da cui derivare poi il BaseEditingController da cui derivano
23
25
  # tutti i controller sottostanti
24
26
  # @default "ApplicationController"
25
- config_accessor :inherited_controller, default: "ApplicationController"
27
+ mattr_accessor :inherited_controller, default: "ApplicationController"
26
28
 
27
29
  ##
28
30
  # Configurazione per alterare lo standard di azione post aggiornamento record
29
31
  # il default è andare nella pagina di editing del record
30
32
  # possibili valori :edit , :index
31
- config_accessor :after_success_update_redirect, default: :edit
33
+ mattr_accessor :after_success_update_redirect, default: :edit
32
34
 
33
35
  ##
34
36
  # Configurazione per alterare lo standard di azione post creazione record
35
37
  # il default è andare nella pagina di editing del record
36
38
  # possibili valori :edit , :index
37
- config_accessor :after_success_create_redirect, default: :edit
39
+ mattr_accessor :after_success_create_redirect, default: :edit
38
40
 
39
41
  ##
40
42
  # Classe che rappresenta l'utente, solitamente User
41
- config_accessor :authentication_model_class, default: "User"
43
+ mattr_accessor :authentication_model_class, default: "User"
42
44
 
43
45
  def self.authentication_model
44
46
  self.authentication_model_class.constantize
@@ -46,12 +48,16 @@ module BaseEditingBootstrap
46
48
 
47
49
  ##
48
50
  # Factory per la creazione del modello che rappresenta l'auteticazione
49
- config_accessor :authentication_model_factory, default: :user
51
+ mattr_accessor :authentication_model_factory, default: :user
50
52
 
51
53
  def self.deprecator
52
54
  @deprecator ||= ActiveSupport::Deprecation.new("2.0", "BaseEditingBootstrap")
53
55
  end
54
56
 
57
+ ##
58
+ # Logger, default to Rails.logger
59
+ mattr_accessor :logger, default: nil
60
+
55
61
  end
56
62
 
57
63
  loader.eager_load
@@ -27,4 +27,10 @@ BaseEditingBootstrap.configure do |config|
27
27
  # Factory per la creazione del modello che rappresenta l'auteticazione
28
28
  # config.authentication_model_factory= :user
29
29
 
30
+ ##
31
+ # Logger, default to Rails.logger
32
+ # @default to Rails.logger or STDOUT if no Rails.logger
33
+ # config.logger = ActiveSupport::TaggedLogging.logger($stdout)
34
+ # config.logger = Rails.logger
35
+
30
36
  end
@@ -8,6 +8,7 @@ RSpec.describe <%= class_name %>, type: :model do
8
8
  # ransack_permitted_associations: [],
9
9
  # option_label_method: :to_s,
10
10
  # ransack_permitted_scopes: [] do
11
+ # let(:option_label_instance){described_class.new} <- default, for override instance to check option_label_method
11
12
  # let(:auth_object) { :auth_object } <- default
12
13
  # let(:auth_object) { create(:user, :as_admin) } <- in caso di necessità di override
13
14
  # let(:new_user_ransack_permitted_attributes) { ransack_permitted_attributes }
@@ -3,6 +3,8 @@ RSpec.shared_examples "a base model" do |ransack_permitted_attributes: [],
3
3
  option_label_method: :to_s,
4
4
  ransack_permitted_scopes: []|
5
5
 
6
+
7
+ let(:option_label_instance){described_class.new}
6
8
  it_behaves_like "a validated? object"
7
9
 
8
10
  it "human_action_message" do
@@ -10,11 +12,10 @@ RSpec.shared_examples "a base model" do |ransack_permitted_attributes: [],
10
12
  end
11
13
 
12
14
  it "have method for belongs_to options" do
13
- instance = described_class.new
14
- expect(instance).to respond_to(:option_label)
15
+ expect(option_label_instance).to respond_to(:option_label)
15
16
 
16
- expect(instance).to receive(option_label_method).and_call_original, "Expected `#{instance.class}#option_label` chiami il metodo `##{option_label_method}` per la traduzione del label nelle options"
17
- instance.option_label
17
+ expect(option_label_instance).to receive(option_label_method).and_call_original, "Expected `#{option_label_instance.class}#option_label` chiami il metodo `##{option_label_method}` per la traduzione del label nelle options"
18
+ option_label_instance.option_label
18
19
  end
19
20
 
20
21
  if ransack_permitted_scopes.any?
@@ -83,3 +84,15 @@ RSpec.shared_examples "a validated? object" do
83
84
  it { is_expected.to be_validated }
84
85
  end
85
86
  end
87
+
88
+ RSpec.shared_examples "a model with custom field_to_form_partial" do |field, partial|
89
+
90
+ it "when #{field}" do
91
+ expect(described_class.field_to_form_partial(field)).to eq partial
92
+ end
93
+
94
+ it "anything else" do
95
+ expect(described_class.field_to_form_partial(anything)).to be_nil
96
+ end
97
+
98
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: base_editing_bootstrap
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.11.0
4
+ version: 1.13.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Marino Bonetti
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2025-09-15 00:00:00.000000000 Z
11
+ date: 2026-02-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -19,7 +19,7 @@ dependencies:
19
19
  version: '7.0'
20
20
  - - "<"
21
21
  - !ruby/object:Gem::Version
22
- version: '8.1'
22
+ version: '9.0'
23
23
  type: :runtime
24
24
  prerelease: false
25
25
  version_requirements: !ruby/object:Gem::Requirement
@@ -29,7 +29,7 @@ dependencies:
29
29
  version: '7.0'
30
30
  - - "<"
31
31
  - !ruby/object:Gem::Version
32
- version: '8.1'
32
+ version: '9.0'
33
33
  - !ruby/object:Gem::Dependency
34
34
  name: pundit
35
35
  requirement: !ruby/object:Gem::Requirement
@@ -400,6 +400,7 @@ files:
400
400
  - lib/base_editing_bootstrap/forms/base.rb
401
401
  - lib/base_editing_bootstrap/generators_helpers.rb
402
402
  - lib/base_editing_bootstrap/is_validated.rb
403
+ - lib/base_editing_bootstrap/logging.rb
403
404
  - lib/base_editing_bootstrap/resource_finder.rb
404
405
  - lib/base_editing_bootstrap/searches/base.rb
405
406
  - lib/base_editing_bootstrap/searches/field.rb