active_scaffold 3.6.15 → 3.6.19

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: 6cc7c6f7e057512476a4f93c0505622a34a97c81b6cbd75c5bb1b014a928ad65
4
- data.tar.gz: c9e2bf9f2240b380b1ebd3f52007db921b88a3035aee3327fec779d74c43f0c6
3
+ metadata.gz: f3e15dbddabba45c8d0c75e9cd91a00b805c2f8d9f229e8c4fc1a9bfa08136dd
4
+ data.tar.gz: 8be97ebe3447c4f77b55e69ee6e6d501c62f342ab49379303a9071c664590a5c
5
5
  SHA512:
6
- metadata.gz: 30377a392938156d9ce545bf18fe0cafebabd935fcd913d4ad28836f53a25cbde41bb7849542f08d6acebdcab9d0e39c8efbddc2d0fe10bf4a40c8af4cedf15e
7
- data.tar.gz: 19602b41999bf34152f9a968c78aa36529794ca7d5ae17db43c55ae288f34b5ed5409923cd1e62ec7a8f5d97f781dd60cce8307c90291136303c3890e0c543e4
6
+ metadata.gz: c351ddf8bbd11a8a2540a6f589197f68a9a520eaba6f446b2f53934dc1c100df14ebe99894d40a97f489a132002645c80db8aa4122bbf09e952f3f6f367a84ea
7
+ data.tar.gz: 35b42d0d6f2d8ffae123b046ede6b5761dfe9910f4922c3dbdf985899c30fbf36fc6696d774d486c888fae774a1c7e390a761fe4f97f8c804b3df1d9b57b95c2
data/CHANGELOG.rdoc CHANGED
@@ -1,3 +1,22 @@
1
+ = 3.6.19
2
+ - Improve create action in has_many through singular association, supporting more cases
3
+
4
+ = 3.6.18
5
+ - Add references only for column.search_joins which are in column.includes, and do search_joins for the rest, search_joins default to includes, so won't change behaviour on most cases, but allows to preload some associations without joining in the query
6
+ - Don't define default search_joins, as it may return includes, so search_joins will default to includes unless is defined, and the previous change won't change the behaviour if user doesn't define search_joins
7
+ - Fix update_columns on through association
8
+
9
+ = 3.6.17
10
+ - Don't add includes or left joins for constrained columns, as they are ignored on sorting clause
11
+ - Fix deprecation on cache counts with rails 5, and fix the queries for rails >= 5.1
12
+ - Fix new for tableless models on rails 5.0
13
+
14
+ = 3.6.16
15
+ - Fix query on paper_trail action
16
+ - Fix one? on tableless relation
17
+ - Fix exists? on tableless relation
18
+ - Fix getting conditions from association in the tableless relation
19
+
1
20
  = 3.6.15
2
21
  - Prevent firing 2 change events on jquery datetime pickers
3
22
  - Fix setting data options on columns for date and datetime pickers
@@ -62,7 +81,7 @@
62
81
  = 3.6.1
63
82
  - Display group cols vertically when subform layout is vertical
64
83
  - Fix html attributes for input datetime on field search, when jquery ui is not used
65
- - Fix constraint columns for nested list on through assocaitions
84
+ - Fix constraint columns for nested list on through associations
66
85
  - Support rails 6.1
67
86
 
68
87
  = 3.6.0
@@ -31,6 +31,22 @@ module ActiveScaffold::Actions
31
31
  params_hash params[:search]
32
32
  end
33
33
 
34
+ def set_outer_joins_for_search(columns)
35
+ references = []
36
+ outer_joins = []
37
+ columns.each do |column|
38
+ next unless column.search_joins.present?
39
+ if column.includes.present? && list_columns.include?(column)
40
+ references << (column.search_joins & column.includes)
41
+ outer_joins << (column.search_joins - column.includes)
42
+ else
43
+ outer_joins << column.search_joins
44
+ end
45
+ end
46
+ active_scaffold_references.concat references.flatten.uniq.compact
47
+ active_scaffold_outer_joins.concat outer_joins.flatten.uniq.compact
48
+ end
49
+
34
50
  def store_search_params_into_session
35
51
  if active_scaffold_config.store_user_settings
36
52
  if params[:search].present?
@@ -100,8 +100,7 @@ module ActiveScaffold::Actions
100
100
  record = params[:id] ? copy_attributes(find_if_allowed(params[:id], :read)) : new_model
101
101
  apply_constraints_to_record(record) unless scope || params[:id]
102
102
  create_association_with_parent record, true if nested?
103
- value = column_value_from_param_value(record, column, value)
104
- record.send "#{column.name}=", value
103
+ update_column_from_params(record, column, value, true)
105
104
  record.id = params[:id]
106
105
  record
107
106
  end
@@ -161,10 +161,14 @@ module ActiveScaffold::Actions
161
161
  search_condition = self.class.condition_for_column(column, value, text_search)
162
162
  next if search_condition.blank?
163
163
 
164
- joins_for_search_on_column(column, count_includes)
165
164
  active_scaffold_conditions << search_condition
166
165
  filtered_columns << column
167
166
  end
167
+ if grouped_search? || active_scaffold_config.list.user.count_includes.present?
168
+ active_scaffold_outer_joins.concat filtered_columns.map(&:search_joins).flatten.uniq.compact
169
+ else
170
+ set_outer_joins_for_search filtered_columns
171
+ end
168
172
  if filtered_columns.present? || grouped_search?
169
173
  @filtered = active_scaffold_config.field_search.human_conditions ? filtered_columns : true
170
174
  end
@@ -172,14 +176,6 @@ module ActiveScaffold::Actions
172
176
  active_scaffold_config.list.user.page = nil
173
177
  end
174
178
 
175
- def joins_for_search_on_column(column, count_includes)
176
- if count_includes.nil? && column.includes.present? && list_columns.include?(column) && !grouped_search?
177
- active_scaffold_references << column.includes
178
- elsif column.search_joins.present?
179
- active_scaffold_outer_joins << column.search_joins
180
- end
181
- end
182
-
183
179
  def field_search_ignore?
184
180
  active_scaffold_config.list.always_show_search && active_scaffold_config.list.search_partial == 'field_search'
185
181
  end
@@ -83,6 +83,7 @@ module ActiveScaffold::Actions
83
83
 
84
84
  def set_includes_for_sorting(columns, sorting)
85
85
  sorting.each_column do |col|
86
+ next if sorting.constraint_columns.include? col.name
86
87
  next unless col.includes.present? && !columns.include?(col)
87
88
  if active_scaffold_config.model.connection.needs_order_expressions_in_select?
88
89
  active_scaffold_references << col.includes
@@ -176,7 +177,7 @@ module ActiveScaffold::Actions
176
177
  query = active_scaffold_config.model.where(active_scaffold_config.primary_key => records.map(&:id))
177
178
  .joins(column.name).group(active_scaffold_config.primary_key)
178
179
  .select("#{klass.quoted_table_name}.#{klass.quoted_primary_key}")
179
- query = query.uniq if column.association.scope && klass.instance_exec(&column.association.scope).values[:distinct]
180
+ query = query.distinct if column.association.scope && klass.instance_exec(&column.association.scope).values[:distinct]
180
181
  query
181
182
  end
182
183
 
@@ -122,16 +122,21 @@ module ActiveScaffold::Actions
122
122
  # has_many is done by beginning_of_chain and rails if direct association, not in through associations
123
123
  return false if nested.has_many? && !nested.association.through?
124
124
  return false if check_match && !nested.match_model?(active_scaffold_config.model)
125
- nested.child_association && nested_parent_record
125
+ (nested.child_association || nested.create_through_singular?) && nested_parent_record
126
126
  end
127
127
 
128
128
  def create_association_with_parent(record, check_match = false)
129
129
  return unless create_association_with_parent?(check_match)
130
- if nested.child_association.singular?
130
+ if nested.child_association&.singular?
131
131
  record.send("#{nested.child_association.name}=", nested_parent_record)
132
- elsif nested.association.through_singular? && nested.child_association.through_singular?
133
- through = nested_parent_record.send(nested.association.through_reflection.name)
134
- record.send("#{nested.child_association.through_reflection.name}=", through)
132
+ elsif nested.create_through_singular?
133
+ through = nested_parent_record.send(nested.association.through_reflection.name) ||
134
+ nested_parent_record.send("build_#{nested.association.through_reflection.name}")
135
+ if nested.source_reflection.reverse_association.collection?
136
+ record.send(nested.source_reflection.reverse) << through
137
+ else
138
+ record.send("#{nested.source_reflection.reverse}=", through)
139
+ end
135
140
  else
136
141
  record.send(nested.child_association.name) << nested_parent_record
137
142
  end
@@ -26,12 +26,7 @@ module ActiveScaffold::Actions
26
26
  @filtered = search_conditions.present?
27
27
  active_scaffold_conditions.concat search_conditions if @filtered
28
28
 
29
- references, outer_joins = columns.partition do |column|
30
- column.includes.present? && list_columns.include?(column)
31
- end
32
- active_scaffold_references.concat references.map(&:includes).flatten.uniq.compact
33
- active_scaffold_outer_joins.concat outer_joins.map(&:search_joins).flatten.uniq.compact
34
-
29
+ set_outer_joins_for_search columns
35
30
  active_scaffold_config.list.user.page = nil
36
31
  else
37
32
  super
@@ -10,7 +10,7 @@ module ActiveScaffold::Actions
10
10
  end
11
11
 
12
12
  def deleted
13
- query = PaperTrail::Version.destroys.where(:item_type => active_scaffold_config.model)
13
+ query = PaperTrail::Version.destroys.where(:item_type => active_scaffold_config.model.name)
14
14
  if nested? && nested.child_association&.belongs_to? && PaperTrail::Version.respond_to?(:where_object)
15
15
  query = query.where_object(nested.child_association.foreign_key => nested.parent_id)
16
16
  end
@@ -353,7 +353,6 @@ module ActiveScaffold::DataStructures
353
353
  if delegated_association
354
354
  self.includes = includes ? [delegated_association.name => includes] : [delegated_association.name]
355
355
  end
356
- self.search_joins = includes.clone if includes
357
356
 
358
357
  # default all the configurable variables
359
358
  self.css_class = ''
@@ -94,12 +94,20 @@ module ActiveScaffold::DataStructures
94
94
  return false unless through_association?
95
95
  return true if association.through_reflection.options[:through] # create not possible, too many levels
96
96
  return true if association.source_reflection.options[:through] # create not possible, too many levels
97
- return false if association.through_singular? # create allowed, AS has code for this
97
+ return false if create_through_singular? # create allowed, AS has code for this
98
98
 
99
99
  # create allowed only if through reflection in record to be created is included in create columns
100
100
  !child_association || !columns.include?(child_association.through_reflection.name)
101
101
  end
102
102
 
103
+ def create_through_singular?
104
+ association.through_singular? && source_reflection.reverse
105
+ end
106
+
107
+ def source_reflection
108
+ @source_reflection ||= ActiveScaffold::DataStructures::Association::ActiveRecord.new(association.source_reflection)
109
+ end
110
+
103
111
  def through_association?
104
112
  association.through?
105
113
  end
@@ -76,6 +76,10 @@ class ActiveScaffold::Tableless < ActiveRecord::Base # rubocop:disable Rails/App
76
76
  super.tap do |scope|
77
77
  if klass < ActiveScaffold::Tableless
78
78
  class << scope; include RelationExtension; end
79
+ assoc_conditions = scope.proxy_association&.send(:association_scope)&.conditions
80
+ if assoc_conditions&.present?
81
+ scope.conditions.concat(assoc_conditions.map { |c| c.is_a?(Hash) ? c[klass.table_name] || c : c })
82
+ end
79
83
  end
80
84
  end
81
85
  end
@@ -112,8 +116,6 @@ class ActiveScaffold::Tableless < ActiveRecord::Base # rubocop:disable Rails/App
112
116
  end
113
117
 
114
118
  module RelationExtension
115
- attr_reader :conditions
116
-
117
119
  def initialize(klass, *)
118
120
  super
119
121
  @conditions ||= []
@@ -124,6 +126,10 @@ class ActiveScaffold::Tableless < ActiveRecord::Base # rubocop:disable Rails/App
124
126
  super
125
127
  end
126
128
 
129
+ def conditions
130
+ @conditions ||= []
131
+ end
132
+
127
133
  def where(opts, *rest)
128
134
  if opts.present?
129
135
  opts = opts.with_indifferent_access if opts.is_a? Hash
@@ -131,6 +137,7 @@ class ActiveScaffold::Tableless < ActiveRecord::Base # rubocop:disable Rails/App
131
137
  end
132
138
  self
133
139
  end
140
+ alias where! where
134
141
 
135
142
  def merge(rel)
136
143
  super.tap do |merged|
@@ -140,14 +147,13 @@ class ActiveScaffold::Tableless < ActiveRecord::Base # rubocop:disable Rails/App
140
147
 
141
148
  def except(*skips)
142
149
  super.tap do |new_relation|
143
- new_relation.conditions = conditions unless skips.include? :where
150
+ unless new_relation.is_a?(RelationExtension)
151
+ class << new_relation; include RelationExtension; end
152
+ end
153
+ new_relation.conditions.concat conditions unless skips.include? :where
144
154
  end
145
155
  end
146
156
 
147
- def to_a
148
- @klass.find_all(self)
149
- end
150
-
151
157
  def find_one(id)
152
158
  @klass.find_one(id, self) || raise(ActiveRecord::RecordNotFound)
153
159
  end
@@ -161,7 +167,15 @@ class ActiveScaffold::Tableless < ActiveRecord::Base # rubocop:disable Rails/App
161
167
  end
162
168
 
163
169
  def exists?
164
- limit(1).to_a.present?
170
+ size.positive?
171
+ end
172
+
173
+ private
174
+
175
+ def exec_queries
176
+ @records = @klass.find_all(self)
177
+ @loaded = true
178
+ @records
165
179
  end
166
180
  end
167
181
 
@@ -203,15 +217,15 @@ class ActiveScaffold::Tableless < ActiveRecord::Base # rubocop:disable Rails/App
203
217
  end
204
218
  end
205
219
  end
206
-
207
- def self.columns_hash
208
- if self < ActiveScaffold::Tableless
209
- @columns_hash ||= Hash[columns.map { |c| [c.name, c] }]
210
- else
211
- super
212
- end
213
- end
214
220
  if Rails.version < '5.0' # 4.2.x
221
+ def self.columns_hash
222
+ if self < ActiveScaffold::Tableless
223
+ @columns_hash ||= Hash[columns.map { |c| [c.name, c] }]
224
+ else
225
+ super
226
+ end
227
+ end
228
+
215
229
  def self.initialize_find_by_cache
216
230
  self.find_by_statement_cache = Hash.new { |h, k| h[k] = StatementCache.new(k) } # rubocop:disable Rails/DynamicFindBy
217
231
  end
@@ -2,7 +2,7 @@ module ActiveScaffold
2
2
  module Version
3
3
  MAJOR = 3
4
4
  MINOR = 6
5
- PATCH = 15
5
+ PATCH = 19
6
6
 
7
7
  STRING = [MAJOR, MINOR, PATCH].compact.join('.')
8
8
  end
@@ -27,8 +27,9 @@ class TablelessTest < MiniTest::Test
27
27
  assert Person.new.files.empty?
28
28
  @person = Person.new
29
29
  @person.save(validate: false)
30
- assert @person.files.empty?
31
- assert_equal [], @person.files.to_a
30
+ assert !@person.files.empty?
31
+ assert @person.files.all.exists?
32
+ assert_equal @person.id, @person.files.first.person_id
32
33
  end
33
34
 
34
35
  def test_tableless_assoc_with_dependent
@@ -6,6 +6,18 @@ class FileModel < ActiveScaffold::Tableless
6
6
  belongs_to :person
7
7
 
8
8
  def self.find_all(relation)
9
+ relation.conditions&.each&.with_index do |condition, i|
10
+ person_id =
11
+ case condition
12
+ when Hash
13
+ condition[:person_id]
14
+ when Arel::Nodes::Equality
15
+ if condition.left.name.to_sym == :person_id
16
+ relation.bind_values[i].present? ? relation.bind_values[i][1] : condition.right.first
17
+ end
18
+ end
19
+ return [new(person_id: person_id)] if person_id
20
+ end
9
21
  []
10
22
  end
11
23
 
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: 3.6.15
4
+ version: 3.6.19
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: 2022-11-28 00:00:00.000000000 Z
11
+ date: 2023-06-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails