active_scaffold 4.2.2 → 4.2.3

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: a411ae5638102ae3b9052929c30afcb44f769c9eeb528fdddd995ba7407bc5b9
4
- data.tar.gz: 0171ab0f4fbde3b09cffae2553d7a7d90248bb5529f548e2321acb525610edd2
3
+ metadata.gz: d279597d030fea168fba4fbcc8cd44c99d02f44b4596c774ec4476db04d53cd1
4
+ data.tar.gz: 48fd530b7990ec28454a1b3adebd5da80ca1d833727b22563a85cef1e140747f
5
5
  SHA512:
6
- metadata.gz: d39d363d9ff5a27b07c124bf7718962d5355c879a77e48f5085f195d739b821276fdbda602078a0995c5385290dd158b2604acf75b863d323ce6ca1ac45d108d
7
- data.tar.gz: 6afacdeacd3fd4b13d0115a8a7c3faba454c2e755bdea68485ebbbdb2c7a305b7022ca833e8960aa4c5df3258ce72236b5959c450d51306049ab652365429a6c
6
+ metadata.gz: 1317103cf2e2344d0340f76f020a7df076f7aedff8f07b1c0a19499338d2d7941e762c51b33757cbcf3cd039d0d9f8bc8b57653282098f23fadfc069fd631bf0
7
+ data.tar.gz: 1300926c2397ea724f788a2b9899397e6c1e0ec6ca5a55a77677edf93dc98e5ed70e1b742c9a6ee8618067e4c378e58899d18e0fba9514e41cbde943c5589c01
data/CHANGELOG.rdoc CHANGED
@@ -1,3 +1,10 @@
1
+ = 4.2.3
2
+ - Make simplified searches on LogicalQueryParser bridge working with upstream gem, no need for my fork
3
+ - Styles for radio form_ui
4
+ - Fix style for checkbox list in subform
5
+ - Fix constraints (broken on 4.2.2 on some cases)
6
+
7
+ = 4.2.2
1
8
  - Support setting form_ui_options with nil, for subforms
2
9
  - Support saving when embedded on through singular association, as it's supported for nested too
3
10
 
@@ -750,6 +750,12 @@ float: left;
750
750
  .active-scaffold li.form-element dd input[type="checkbox"] {
751
751
  margin-top: 6px;
752
752
  }
753
+ .active-scaffold form input[type=radio] {
754
+ margin-right: 5px;
755
+ }
756
+ .active-scaffold form label:has(input[type=radio]) {
757
+ margin-right: 10px;
758
+ }
753
759
 
754
760
  .active-scaffold li.form-element dd .select-field:not(.draggable-lists-container) {
755
761
  display: inline-block;
@@ -1039,7 +1045,7 @@ padding: 0 2px 2px 2px;
1039
1045
  border: solid 1px;
1040
1046
  }
1041
1047
 
1042
- .active-scaffold .sub-form .checkbox-list label {
1048
+ .active-scaffold .sub-form .checkbox-list li {
1043
1049
  display: block;
1044
1050
  }
1045
1051
 
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'method_source'
4
+
5
+ class ActiveScaffold::Bridges::LogicalQueryParser
6
+ class KeywordQueryParser
7
+ LogicalQueryParser.singleton_methods.each do |method_name|
8
+ method = LogicalQueryParser.method(method_name)
9
+ define_method(method_name, &method)
10
+ end
11
+
12
+ # Copy search method from LogicalQueryParser
13
+ class_eval(LogicalQueryParser.method(:search).source, __FILE__, __LINE__)
14
+
15
+ def initialize(operator)
16
+ @operator = operator
17
+ end
18
+
19
+ def new
20
+ ActiveScaffold::Bridges::LogicalQueryParser::TokensGrammar::Parser.new(@operator)
21
+ end
22
+ end
23
+ end
@@ -1,9 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class ActiveScaffold::Bridges::LogicalQueryParser < ActiveScaffold::DataStructures::Bridge
4
+ autoload :TokensGrammar, 'active_scaffold/bridges/logical_query_parser/tokens_grammar'
5
+ autoload :KeywordQueryParser, 'active_scaffold/bridges/logical_query_parser/keyword_query_parser'
6
+
4
7
  def self.install
5
- require File.join(File.dirname(__FILE__), 'logical_query_parser/tokens_grammar')
6
- ActiveScaffold::Finder.send(:remove_const, :LOGICAL_COMPARATORS)
7
8
  ActiveScaffold::Finder.const_set :LOGICAL_COMPARATORS, %w[all_tokens any_token logical].freeze
8
9
  end
9
10
  end
@@ -155,6 +155,41 @@ module ActiveScaffold
155
155
  "Malformed constraint `#{klass}##{column_name}'. If it's a legitimate column, and you are using a nested scaffold, please specify or double-check the reverse association name."
156
156
  end
157
157
 
158
+ def apply_constraint_on_association(record, association, value, allow_autosave: false)
159
+ if association.through_singular? && association.source_reflection.reverse
160
+ create_on_through_singular(record, association, association.klass.find(value))
161
+ elsif association.collection?
162
+ record.send(k.to_s).send(:<<, association.klass.find(value)) unless association.nested?
163
+ elsif association.polymorphic?
164
+ apply_constraint_on_polymorphic_association(record, association, value)
165
+ elsif !association.source_reflection&.through? && # regular singular association, or one-level through association
166
+ !value.is_a?(Array)
167
+ record.send(:"#{association.name}=", association.klass.find(value))
168
+
169
+ # setting the belongs_to side of a has_one isn't safe. if the has_one was already
170
+ # specified, rails won't automatically clear out the previous associated record.
171
+ #
172
+ # note that we can't take the extra step to correct this unless we're permitted to
173
+ # run operations where activerecord auto-saves the object.
174
+ reverse = association.reverse_association
175
+ if reverse&.singular? && !reverse.belongs_to? && allow_autosave
176
+ record.send(association.name).send(:"#{reverse.name}=", record)
177
+ end
178
+ end
179
+ end
180
+
181
+ def apply_constraint_on_polymorphic_association(record, association, value)
182
+ unless value.is_a?(Array) && value.size >= 2
183
+ raise ActiveScaffold::MalformedConstraint, polymorphic_constraint_error(association), caller
184
+ end
185
+
186
+ if value.size == 2
187
+ record.send(:"#{association.name}=", value[0].constantize.find(value[1]))
188
+ else
189
+ record.send(:"#{association.foreign_type}=", value[0])
190
+ end
191
+ end
192
+
158
193
  # Applies constraints to the given record.
159
194
  #
160
195
  # Searches through the known columns for association columns. If the given constraint is an association,
@@ -163,42 +198,12 @@ module ActiveScaffold
163
198
  #
164
199
  # For some operations ActiveRecord will automatically update the database. That's not always ok.
165
200
  # If it *is* ok (e.g. you're in a transaction), then set :allow_autosave to true.
166
- def apply_constraints_to_record(record, options = {})
167
- options[:allow_autosave] = false if options[:allow_autosave].nil?
168
- constraints = options[:constraints] || active_scaffold_constraints
169
-
201
+ def apply_constraints_to_record(record, allow_autosave: false, constraints: active_scaffold_constraints)
170
202
  config = record.is_a?(active_scaffold_config.model) ? active_scaffold_config : active_scaffold_config_for(record.class)
171
203
  constraints.each do |k, v|
172
204
  column = config.columns[k]
173
205
  if column&.association
174
- if column.association.through_singular? && column.association.source_reflection.reverse
175
- create_on_through_singular(record, column.association, column.association.klass.find(v))
176
- elsif column.association.collection?
177
- record.send(k.to_s).send(:<<, column.association.klass.find(v)) unless column.association.nested?
178
- elsif column.association.polymorphic?
179
- unless v.is_a?(Array) && v.size >= 2
180
- raise ActiveScaffold::MalformedConstraint, polymorphic_constraint_error(column.association), caller
181
- end
182
-
183
- if v.size == 2
184
- record.send(:"#{k}=", v[0].constantize.find(v[1]))
185
- else
186
- record.send(:"#{column.association.foreign_type}=", v[0])
187
- end
188
- elsif !column.association.source_reflection&.through? && # regular singular association, or one-level through association
189
- !v.is_a?(Array)
190
- record.send(:"#{k}=", column.association.klass.find(v))
191
-
192
- # setting the belongs_to side of a has_one isn't safe. if the has_one was already
193
- # specified, rails won't automatically clear out the previous associated record.
194
- #
195
- # note that we can't take the extra step to correct this unless we're permitted to
196
- # run operations where activerecord auto-saves the object.
197
- reverse = column.association.reverse_association
198
- if reverse&.singular? && !reverse.belongs_to? && options[:allow_autosave]
199
- record.send(k).send(:"#{reverse.name}=", record)
200
- end
201
- end
206
+ apply_constraint_on_association(record, column.association, v, allow_autosave: allow_autosave)
202
207
  else
203
208
  record.send(:"#{k}=", v)
204
209
  end
@@ -346,7 +346,7 @@ module ActiveScaffold::DataStructures
346
346
  end
347
347
 
348
348
  def searchable?
349
- search_sql.present? || (logical_search.present? && ActiveScaffold::Finder::LOGICAL_COMPARATORS.present?)
349
+ search_sql.present? || (logical_search.present? && ActiveScaffold::Finder.logical_comparators.present?)
350
350
  end
351
351
 
352
352
  def link
@@ -6,6 +6,10 @@ module ActiveScaffold
6
6
  @@like_operator ||= ::ActiveRecord::Base.connection.adapter_name.in?(%w[PostgreSQL PostGIS]) ? 'ILIKE' : 'LIKE'
7
7
  end
8
8
 
9
+ def self.logical_comparators
10
+ ActiveScaffold::Finder::LOGICAL_COMPARATORS if ActiveScaffold::Finder.const_defined? :LOGICAL_COMPARATORS
11
+ end
12
+
9
13
  module ClassMethods
10
14
  def self.extended(klass)
11
15
  return unless klass.active_scaffold_config
@@ -231,21 +235,21 @@ module ActiveScaffold
231
235
  ['(%<search_sql>s BETWEEN ? AND ?)', value[:from], value[:to]]
232
236
  elsif ActiveScaffold::Finder::NUMERIC_COMPARATORS.include?(value[:opt])
233
237
  ["%<search_sql>s #{value[:opt]} ?", value[:from]]
234
- elsif ActiveScaffold::Finder::LOGICAL_COMPARATORS.include?(value[:opt])
238
+ elsif ActiveScaffold::Finder.logical_comparators&.include?(value[:opt])
235
239
  operator =
236
240
  case value[:opt]
237
241
  when 'all_tokens' then 'AND'
238
242
  when 'any_token' then 'OR'
239
243
  end
240
- parser = ActiveScaffold::Bridges::LogicalQueryParser::TokensGrammar::Parser.new(operator) if operator
241
- [logical_search_condition(column, value[:from], parser)]
244
+ parser = ActiveScaffold::Bridges::LogicalQueryParser::KeywordQueryParser.new(operator) if operator
245
+ [logical_search_condition(column, value[:from], parser || ::LogicalQueryParser)]
242
246
  end
243
247
  end
244
248
 
245
- def logical_search_condition(column, search, parser = nil)
249
+ def logical_search_condition(column, search, parser)
246
250
  model = column.active_record_class
247
251
  subquery = alias_query_for_same_table_exists(model.all) if column.logical_search.any?(Hash)
248
- query = ::LogicalQueryParser.search(search, subquery || model, column.logical_search, parser: parser)
252
+ query = parser.search(search, subquery || model, column.logical_search)
249
253
  if subquery
250
254
  model.where(same_table_exists_subquery(query))
251
255
  else
@@ -526,7 +530,6 @@ module ActiveScaffold
526
530
  doesnt_begin_with: 'not_?%',
527
531
  doesnt_end_with: 'not_%?'
528
532
  }.freeze
529
- LOGICAL_COMPARATORS = [].freeze
530
533
  NULL_COMPARATORS = %w[null not_null].freeze
531
534
  DATE_COMPARATORS = %w[PAST FUTURE RANGE].freeze
532
535
  DATE_UNITS = %w[DAYS WEEKS MONTHS YEARS].freeze
@@ -213,8 +213,8 @@ module ActiveScaffold
213
213
  if column.search_sql.present?
214
214
  select_options.concat(ActiveScaffold::Finder::STRING_COMPARATORS.collect { |title, comp| [as_(title), comp] })
215
215
  end
216
- if ActiveScaffold::Finder::LOGICAL_COMPARATORS.present? && column.logical_search.present?
217
- select_options.concat(ActiveScaffold::Finder::LOGICAL_COMPARATORS.collect { |comp| [as_(comp.downcase.to_sym), comp] })
216
+ if ActiveScaffold::Finder.logical_comparators.present? && column.logical_search.present?
217
+ select_options.concat(ActiveScaffold::Finder.logical_comparators.collect { |comp| [as_(comp.downcase.to_sym), comp] })
218
218
  end
219
219
  end
220
220
  if column.search_sql.present?
@@ -4,7 +4,7 @@ module ActiveScaffold
4
4
  module Version
5
5
  MAJOR = 4
6
6
  MINOR = 2
7
- PATCH = 2
7
+ PATCH = 3
8
8
  FIX = nil
9
9
 
10
10
  STRING = [MAJOR, MINOR, PATCH, FIX].compact.join('.')
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: active_scaffold
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.2.2
4
+ version: 4.2.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Many, see README
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2026-02-20 00:00:00.000000000 Z
11
+ date: 2026-02-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: dartsass-sprockets
@@ -38,6 +38,20 @@ dependencies:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0.11'
41
+ - !ruby/object:Gem::Dependency
42
+ name: method_source
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '1.1'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '1.1'
41
55
  - !ruby/object:Gem::Dependency
42
56
  name: rails
43
57
  requirement: !ruby/object:Gem::Requirement
@@ -242,6 +256,7 @@ files:
242
256
  - lib/active_scaffold/bridges/file_column/test/functional/file_column_keep_test.rb
243
257
  - lib/active_scaffold/bridges/file_column/test/mock_model.rb
244
258
  - lib/active_scaffold/bridges/logical_query_parser.rb
259
+ - lib/active_scaffold/bridges/logical_query_parser/keyword_query_parser.rb
245
260
  - lib/active_scaffold/bridges/logical_query_parser/tokens_grammar.rb
246
261
  - lib/active_scaffold/bridges/logical_query_parser/tokens_grammar.treetop
247
262
  - lib/active_scaffold/bridges/paper_trail.rb