active_scaffold 3.6.0.rc1 → 3.6.2
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 +4 -4
- data/CHANGELOG.rdoc +26 -0
- data/README.md +10 -9
- data/app/assets/javascripts/jquery/active_scaffold.js +48 -14
- data/app/assets/stylesheets/active_scaffold_layout.css +1 -1
- data/app/views/active_scaffold_overrides/_form_association.html.erb +2 -1
- data/app/views/active_scaffold_overrides/_form_association_record.html.erb +22 -6
- data/app/views/active_scaffold_overrides/_horizontal_subform.html.erb +3 -3
- data/app/views/active_scaffold_overrides/_horizontal_subform_header.html.erb +2 -1
- data/app/views/active_scaffold_overrides/_vertical_subform.html.erb +2 -2
- data/app/views/active_scaffold_overrides/update_column.js.erb +1 -1
- data/lib/active_scaffold/actions/core.rb +5 -2
- data/lib/active_scaffold/actions/list.rb +1 -1
- data/lib/active_scaffold/actions/nested.rb +1 -1
- data/lib/active_scaffold/actions/subform.rb +12 -6
- data/lib/active_scaffold/attribute_params.rb +6 -16
- data/lib/active_scaffold/bridges/active_storage/active_storage_bridge.rb +1 -0
- data/lib/active_scaffold/bridges/active_storage/list_ui.rb +4 -4
- data/lib/active_scaffold/bridges/bitfields.rb +1 -1
- data/lib/active_scaffold/bridges/bitfields/list_ui.rb +19 -0
- data/lib/active_scaffold/bridges/paper_trail/actions.rb +3 -1
- data/lib/active_scaffold/bridges/record_select/helpers.rb +3 -1
- data/lib/active_scaffold/config/list.rb +1 -1
- data/lib/active_scaffold/data_structures/action_columns.rb +1 -1
- data/lib/active_scaffold/data_structures/association/abstract.rb +1 -4
- data/lib/active_scaffold/data_structures/nested_info.rb +14 -2
- data/lib/active_scaffold/extensions/action_view_rendering.rb +66 -25
- data/lib/active_scaffold/extensions/localize.rb +1 -1
- data/lib/active_scaffold/finder.rb +7 -5
- data/lib/active_scaffold/helpers/controller_helpers.rb +11 -0
- data/lib/active_scaffold/helpers/form_column_helpers.rb +52 -15
- data/lib/active_scaffold/helpers/list_column_helpers.rb +10 -6
- data/lib/active_scaffold/helpers/search_column_helpers.rb +14 -7
- data/lib/active_scaffold/helpers/view_helpers.rb +1 -1
- data/lib/active_scaffold/tableless.rb +16 -2
- data/lib/active_scaffold/version.rb +1 -1
- data/lib/generators/active_scaffold/install_generator.rb +51 -3
- data/test/data_structures/action_columns_test.rb +1 -1
- data/test/extensions/action_view_rendering_test.rb +20 -0
- data/test/misc/constraints_test.rb +1 -1
- data/test/misc/tableless_test.rb +8 -0
- data/test/mock_app/app/controllers/people_controller.rb +2 -0
- data/test/mock_app/app/controllers/roles_controller.rb +4 -0
- data/test/mock_app/app/views/active_scaffold_overrides/_form.html.erb +2 -0
- data/test/mock_app/app/views/active_scaffold_overrides/list.html.erb +2 -0
- data/test/mock_app/app/views/people/_first_name_form_column.html.erb +2 -0
- data/test/mock_app/app/views/people/_form.html.erb +2 -0
- data/test/mock_app/app/views/people/list.html.erb +2 -0
- data/test/test_helper.rb +2 -2
- metadata +25 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: d35f441c2847444fd7e591e529085d3613774e19b0dc2b87a6a7e046e39eb95a
|
|
4
|
+
data.tar.gz: 5028894d44f4ed52a7e3cf7f4f92d38d86c48221815ccbb2f28396ecbda447ec
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 0d92dc0e4e6933a0849269191d4b273083e6914606a3198ccd132754f1ef4607434d7ef5cf6e51268aa34c7c926613f75214aa5b1ac961a0784ca5b8a34133c3
|
|
7
|
+
data.tar.gz: b87a086b26a98a148a485fe9af2c55e483dbbb82a1ccc4231d7e468a4f5265022bef3899e05ae6e6af1fef63295456f43f2456ba17043f42e42a7a796bcdffde
|
data/CHANGELOG.rdoc
CHANGED
|
@@ -1,3 +1,29 @@
|
|
|
1
|
+
= 3.6.2
|
|
2
|
+
- Fix count query when association's primary key is string
|
|
3
|
+
- Fix unauthorized_columns and constraint_columns with threadsafe enabled
|
|
4
|
+
- Fix changing list.sorting and column.sort_by per request when threadsafe is enabled
|
|
5
|
+
|
|
6
|
+
= 3.6.1
|
|
7
|
+
- Display group cols vertically when subform layout is vertical
|
|
8
|
+
- Fix html attributes for input datetime on field search, when jquery ui is not used
|
|
9
|
+
- Fix constraint columns for nested list on through assocaitions
|
|
10
|
+
- Support rails 6.1
|
|
11
|
+
|
|
12
|
+
= 3.6.0
|
|
13
|
+
- Fix i18n at ruby 3.0.0
|
|
14
|
+
- Add list helper for bitfield column, so it display labels of selected checkboxes in list
|
|
15
|
+
- Support rails 6.0
|
|
16
|
+
|
|
17
|
+
= 3.6.0.rc2
|
|
18
|
+
- Fix subform crud in subform subgroup when controller is embedded
|
|
19
|
+
- Fix sorting for mongoid models, broken in 3.6.0.rc1
|
|
20
|
+
- Improve add_new option, allow to change subform columns (with helper override calling super and add columns to locals argument)
|
|
21
|
+
- Support add_new option for record_select or radio form_ui
|
|
22
|
+
- Support add_new option for polymorphic associations (add_new may be array with class names to allow add new, or true to allow add new for any model)
|
|
23
|
+
- Support description for columns displayed as subform
|
|
24
|
+
- Don't mess with history if current page is not using activescaffold when is loaded
|
|
25
|
+
- Fix changing sort_by per request when threadsafe is enabled
|
|
26
|
+
|
|
1
27
|
= 3.6.0.rc1
|
|
2
28
|
- Cleanup: deprecate ActiveScaffold.set_defaults for ActiveScaffold.defaults, rename some setters
|
|
3
29
|
- Fix adding new action links on request with threadsafety enabled
|
data/README.md
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
+
|
|
1
2
|
Overview
|
|
2
3
|
========
|
|
3
|
-
[](https://travis-ci.com/activescaffold/active_scaffold)
|
|
4
5
|
[](https://codeclimate.com/github/activescaffold/active_scaffold)
|
|
5
6
|
[](https://codeclimate.com/github/activescaffold/active_scaffold)
|
|
6
7
|
[](https://gemnasium.com/activescaffold/active_scaffold)
|
|
@@ -8,13 +9,13 @@ Overview
|
|
|
8
9
|
[](https://inch-ci.org/github/activescaffold/active_scaffold)
|
|
9
10
|
[](https://opensource.org/licenses/MIT)
|
|
10
11
|
|
|
11
|
-
ActiveScaffold provides a quick and powerful user interfaces for CRUD (create, read, update, delete) operations for Rails applications. It offers additonal features including searching, pagination & layout control. Rails >= 4.2.0 is supported, ruby >= 2.3 required.
|
|
12
|
+
ActiveScaffold provides a quick and powerful user interfaces for CRUD (create, read, update, delete) operations for Rails applications. It offers additonal features including searching, pagination & layout control. Rails >= 4.2.0 and Rails <= 6.1 is supported, ruby >= 2.3 required.
|
|
12
13
|
|
|
13
14
|
Branch Details
|
|
14
15
|
--------------
|
|
15
|
-
3-5-stable supports rails >= 4.0.x and ruby >= 2.0.0
|
|
16
|
-
3-4-stable supports rails >= 3.2.x and ruby >= 1.9.3
|
|
17
|
-
3-3-stable supports rails
|
|
16
|
+
3-5-stable supports rails >= 4.0.x and <= 5.1.x, and ruby >= 2.0.0
|
|
17
|
+
3-4-stable supports rails >= 3.2.x and <= 4.2.x, and ruby >= 1.9.3
|
|
18
|
+
3-3-stable supports rails 3.2.x and ruby >= 1.8
|
|
18
19
|
rails-3.2 supports Rails 3.1 & 3.2, and is the current source of the 3.2.x line of gems.
|
|
19
20
|
|
|
20
21
|
Quick Start
|
|
@@ -25,12 +26,12 @@ Added to Gemfile
|
|
|
25
26
|
|
|
26
27
|
gem 'active_scaffold'
|
|
27
28
|
|
|
28
|
-
For rails >= 5.1, add jquery to application.js before rails-ujs
|
|
29
|
-
|
|
30
|
-
//= require jquery
|
|
29
|
+
For rails >= 5.1, add jquery-rails to Gemfile, and install generator will jquery to application.js before rails-ujs. Also it's possible to load jquery in your layout before application.js using CDN (e.g. jquery-rails-cdn). You can replace rails-ujs with jquery_ujs, although rails-ujs should work (never load both).
|
|
31
30
|
|
|
32
31
|
gem 'jquery-rails'
|
|
33
32
|
|
|
33
|
+
For rails >= 6.0, installer generator will create app/assets/javascripts/application.js, add it to assets.precompile array and add javascript_include_tag in layout, as ActiveScaffold doesn't work with webpack yet. Jquery may be loaded by packs or assets pipeline.
|
|
34
|
+
|
|
34
35
|
Run the following commands, for rails 4.2
|
|
35
36
|
|
|
36
37
|
bundle install
|
|
@@ -39,7 +40,7 @@ Run the following commands, for rails 4.2
|
|
|
39
40
|
rails g active_scaffold:resource Model [attrs]
|
|
40
41
|
bundle exec rake db:migrate
|
|
41
42
|
|
|
42
|
-
Or run the following commands, for rails 5
|
|
43
|
+
Or run the following commands, for rails >= 5
|
|
43
44
|
|
|
44
45
|
bundle install
|
|
45
46
|
rails g active_scaffold:install
|
|
@@ -323,20 +323,34 @@ jQuery(document).ready(function($) {
|
|
|
323
323
|
if (jQuery(this).prop('checked')) color_field.val('');
|
|
324
324
|
});
|
|
325
325
|
|
|
326
|
-
jQuery(document).on('click', '.show-new-subform', function(e) {
|
|
327
|
-
e.preventDefault();
|
|
326
|
+
jQuery(document).on('click', '.hide-new-subform, .show-new-subform', function(e) {
|
|
328
327
|
var $this = jQuery(this), line = $this.closest('.form-element'),
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
subform.show().find("input:disabled,select:disabled,textarea:disabled").prop('disabled', false);
|
|
334
|
-
$this.data('select-text', $this.html());
|
|
335
|
-
$this.html($this.data('subform-text'));
|
|
328
|
+
subform = line.find('#' + $this.data('subform-id')), radio = false, hide, select;
|
|
329
|
+
if ($this.is('[type=radio]')) {
|
|
330
|
+
radio = true;
|
|
331
|
+
hide = $this.is('.hide-new-subform');
|
|
336
332
|
} else {
|
|
333
|
+
e.preventDefault();
|
|
334
|
+
hide = subform.is(':visible');
|
|
335
|
+
}
|
|
336
|
+
if ($this.data('select-id')) {
|
|
337
|
+
select = line.find('#' + $this.data('select-id'));
|
|
338
|
+
if (select.hasClass('recordselect') || select.is('.no-options')) select = select.next(':hidden').andSelf();
|
|
339
|
+
}
|
|
340
|
+
if (hide) {
|
|
337
341
|
subform.hide().find("input:enabled,select:enabled,textarea:enabled").prop('disabled', true);
|
|
338
|
-
select.show().prop('disabled', false);
|
|
339
|
-
|
|
342
|
+
if (select) select.show().prop('disabled', false);
|
|
343
|
+
if (radio) {
|
|
344
|
+
$this.closest('.form-element').find('[name="' + $this.attr('name') + '"].show-new-subform').prop('disabled', false);
|
|
345
|
+
} else $this.html($this.data('select-text'));
|
|
346
|
+
} else {
|
|
347
|
+
if (select) select.hide().prop('disabled', true);
|
|
348
|
+
subform.show().find("input:disabled,select:disabled,textarea:disabled").prop('disabled', false);
|
|
349
|
+
if (radio) $this.prop('disabled', true);
|
|
350
|
+
else {
|
|
351
|
+
$this.data('select-text', $this.html());
|
|
352
|
+
$this.html($this.data('subform-text'));
|
|
353
|
+
}
|
|
340
354
|
}
|
|
341
355
|
});
|
|
342
356
|
|
|
@@ -500,6 +514,7 @@ var ActiveScaffold = {
|
|
|
500
514
|
ActiveScaffold.disable_optional_subforms(container);
|
|
501
515
|
},
|
|
502
516
|
setup_history_state: function() {
|
|
517
|
+
if (!jQuery('.active-scaffold').length) return;
|
|
503
518
|
var data = {}, current_search_item = jQuery('.active-scaffold .filtered-message[data-search]');
|
|
504
519
|
if (current_search_item.length) {
|
|
505
520
|
// store user settings enabled, update state with current page, search and sorting
|
|
@@ -536,8 +551,27 @@ var ActiveScaffold = {
|
|
|
536
551
|
jQuery('.as-js-button', element).show();
|
|
537
552
|
},
|
|
538
553
|
disable_optional_subforms: function(element) {
|
|
539
|
-
jQuery('.
|
|
540
|
-
jQuery(
|
|
554
|
+
jQuery('.sub-form.optional', element).each(function () {
|
|
555
|
+
var $this = jQuery(this), toggle = $this.find('>.visibility-toggle');
|
|
556
|
+
if (toggle.length) {
|
|
557
|
+
var hide = toggle.text() == toggle.data('show');
|
|
558
|
+
$this.find('> [id] > .sub-form-record > .associated-record dl:first').each(function (i) {
|
|
559
|
+
var parent = jQuery(this).parent(), div_id = toggle.data('toggable') + i;
|
|
560
|
+
parent.children().wrapAll('<div id="' + div_id + '">');
|
|
561
|
+
if (hide) parent.find('> div').hide();
|
|
562
|
+
parent.prepend(toggle.clone().data('toggable', div_id));
|
|
563
|
+
});
|
|
564
|
+
toggle.remove();
|
|
565
|
+
}
|
|
566
|
+
if ($this.is(':visible')) {
|
|
567
|
+
var line = $this.closest('.form-element'), toggle = line.find('.show-new-subform[data-subform-id="' + $this.attr('id') + '"]').first();
|
|
568
|
+
if (toggle.is('[type=radio]')) toggle.prop('disabled', true);
|
|
569
|
+
else if (toggle.data('select-id')) {
|
|
570
|
+
select = line.find('#' + toggle.data('select-id'));
|
|
571
|
+
if (select.hasClass('recordselect') || select.is('.no-options')) select = select.next(':hidden').andSelf();
|
|
572
|
+
select.hide().prop('disabled', true);
|
|
573
|
+
}
|
|
574
|
+
} else $this.find("input:enabled,select:enabled,textarea:enabled").prop('disabled', true);
|
|
541
575
|
});
|
|
542
576
|
},
|
|
543
577
|
sliders: function(element) {
|
|
@@ -1430,7 +1464,7 @@ ActiveScaffold.ActionLink.Table = ActiveScaffold.ActionLink.Abstract.extend({
|
|
|
1430
1464
|
else {
|
|
1431
1465
|
throw 'Unknown position "' + this.position + '"'
|
|
1432
1466
|
}
|
|
1433
|
-
ActiveScaffold.highlight(this.adapter.find('td').first().children());
|
|
1467
|
+
ActiveScaffold.highlight(this.adapter.find('td').first().children().not('script'));
|
|
1434
1468
|
ActiveScaffold.focus_first_element_of_form(this.adapter);
|
|
1435
1469
|
}
|
|
1436
1470
|
});
|
|
@@ -13,8 +13,9 @@ footer = render(:partial => 'form_association_footer', :locals => {:parent_recor
|
|
|
13
13
|
-%>
|
|
14
14
|
<h5>
|
|
15
15
|
<%= column.label -%>
|
|
16
|
-
<%= link_to_visibility_toggle(subform_div_id,
|
|
16
|
+
<%= link_to_visibility_toggle(subform_div_id, default_visible: !column.collapsed) -%>
|
|
17
17
|
</h5>
|
|
18
|
+
<%= content_tag :span, column.description, class: 'description' if column.description.present? %>
|
|
18
19
|
<div id ="<%= subform_div_id %>" <%= 'style="display: none;"'.html_safe if column.collapsed -%>>
|
|
19
20
|
<%# HACK: to be able to delete all associated records %>
|
|
20
21
|
<%= hidden_field_tag "#{(opts = active_scaffold_input_options(column, scope, :object => parent_record))[:name]}[0]", '', :id => "#{opts[:id]}_0" if column.association.collection? %>
|
|
@@ -6,11 +6,13 @@
|
|
|
6
6
|
show_actions = false
|
|
7
7
|
locked ||= false
|
|
8
8
|
config = active_scaffold_config_for(record.class)
|
|
9
|
+
columns ||= config.subform.columns
|
|
9
10
|
scope = column_scope(record_column, scope, record)
|
|
10
11
|
options = active_scaffold_input_options(config.columns[record.class.primary_key], scope, :object => record)
|
|
11
12
|
tr_id = "association-#{options[:id]}"
|
|
13
|
+
layout ||= config.subform.layout
|
|
12
14
|
|
|
13
|
-
if
|
|
15
|
+
if layout == :vertical
|
|
14
16
|
record_tag ||= :div
|
|
15
17
|
row_tag ||= :ol
|
|
16
18
|
column_tag ||= :li
|
|
@@ -40,7 +42,7 @@
|
|
|
40
42
|
<% end %>
|
|
41
43
|
<% end %>
|
|
42
44
|
<%= content_tag row_tag, :id => tr_id, :class => "association-record#{' association-record-new' if record.new_record?}#{' locked' if locked}" do %>
|
|
43
|
-
<%
|
|
45
|
+
<% columns.each_column(for: record.class, crud_type: :read, flatten: flatten) do |column| %>
|
|
44
46
|
<%
|
|
45
47
|
if column.respond_to? :each_column
|
|
46
48
|
columns_groups << column
|
|
@@ -82,10 +84,24 @@
|
|
|
82
84
|
|
|
83
85
|
<% columns_groups.each do |columns_group| %>
|
|
84
86
|
<%= content_tag row_tag, :class => 'associated-record' do %>
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
87
|
+
<% if layout == :vertical %>
|
|
88
|
+
<% columns_group.each_column(for: record.class, crud_type: :read, flatten: true) do |col| %>
|
|
89
|
+
<%
|
|
90
|
+
col_class = default_col_class.clone
|
|
91
|
+
col_class << 'required' if col.required?
|
|
92
|
+
col_class << col.css_class unless col.css_class.nil? || col.css_class.is_a?(Proc)
|
|
93
|
+
col_class << 'hidden' if column_renders_as(col) == :hidden
|
|
94
|
+
%>
|
|
95
|
+
<%= content_tag column_tag, :class => col_class, :colspan => (columns_length if column_tag == :td) do %>
|
|
96
|
+
<%= active_scaffold_render_subform_column(col, scope, crud_type, readonly, false, record) %>
|
|
97
|
+
<% end %>
|
|
98
|
+
<% end %>
|
|
99
|
+
<% else %>
|
|
100
|
+
<%= content_tag column_tag, :colspan => (columns_length if column_tag == :td) do %>
|
|
101
|
+
<% columns_group.each_column(for: record.class, crud_type: :read, flatten: true) do |col| %>
|
|
102
|
+
<%= active_scaffold_render_subform_column(col, scope, crud_type, readonly, true, record) %>
|
|
103
|
+
<% end %>
|
|
104
|
+
<% end %>
|
|
89
105
|
<% end %>
|
|
90
106
|
<% end %>
|
|
91
107
|
<% end %>
|
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
<%
|
|
3
3
|
header_record_class = (show_blank_record && show_blank_record.class) || column.association.klass
|
|
4
4
|
-%>
|
|
5
|
-
<%= render :
|
|
5
|
+
<%= render partial: 'horizontal_subform_header', :locals => {parent_record: parent_record, record_class: header_record_class, parent_column: column, columns: local_assigns[:columns]} %>
|
|
6
6
|
|
|
7
|
-
<%= render :
|
|
8
|
-
<%= render :
|
|
7
|
+
<%= render partial: 'form_association_record', collection: associated, locals: {scope: scope, parent_record: parent_record, column: column, columns: local_assigns[:columns], layout: :horizontal} %>
|
|
8
|
+
<%= render partial: 'form_association_record', object: show_blank_record, locals: {scope: scope, parent_record: parent_record, column: column, columns: local_assigns[:columns], layout: :horizontal, locked: true, index: associated.size} if show_blank_record %>
|
|
9
9
|
<tfoot>
|
|
10
10
|
<%= render :partial => 'horizontal_subform_footer', :locals => {:scope => scope, :parent_record => parent_record, :column => column} %>
|
|
11
11
|
</tfoot>
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
<thead>
|
|
2
2
|
<tr>
|
|
3
3
|
<%
|
|
4
|
-
active_scaffold_config_for(record_class).subform.columns
|
|
4
|
+
columns ||= active_scaffold_config_for(record_class).subform.columns
|
|
5
|
+
columns.each_column(for: record_class, crud_type: :read) do |column|
|
|
5
6
|
next unless column.is_a? ActiveScaffold::DataStructures::Column
|
|
6
7
|
next unless in_subform?(column, parent_record, parent_column)
|
|
7
8
|
hidden = column_renders_as(column) == :hidden
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
<div id="<%= sub_form_list_id(:association => column.name, :id => parent_record.id || generated_id(parent_record) || 99999999999) %>">
|
|
2
|
-
<%= render :
|
|
3
|
-
<%= render :
|
|
2
|
+
<%= render partial: 'form_association_record', collection: associated, locals: {scope: scope, parent_record: parent_record, column: column, columns: local_assigns[:columns], layout: :vertical} %>
|
|
3
|
+
<%= render partial: 'form_association_record', object: show_blank_record, locals: {scope: scope, parent_record: parent_record, column: column, columns: local_assigns[:columns], layout: :vertical, locked: true, index: associated.size} if show_blank_record %>
|
|
4
4
|
</div>
|
|
@@ -22,5 +22,5 @@
|
|
|
22
22
|
ActiveScaffold.replace_html('<%= @column_span_id %>','<%= escape_javascript(get_column_value(@record, @column)) %>');
|
|
23
23
|
<% end -%>
|
|
24
24
|
<% if @column.calculation? -%>
|
|
25
|
-
ActiveScaffold.replace_html('<%= active_scaffold_calculations_id(:column => @column) %>', '<%= escape_javascript(render_column_calculation(@column)) %>');
|
|
25
|
+
ActiveScaffold.replace_html('<%= active_scaffold_calculations_id(:column => @column) %>', '<%= escape_javascript(render_column_calculation(@column, id_condition: false)) %>');
|
|
26
26
|
<% end -%>
|
|
@@ -72,7 +72,8 @@ module ActiveScaffold::Actions
|
|
|
72
72
|
else
|
|
73
73
|
updated_record_with_column(@column, params.delete(:value), @scope)
|
|
74
74
|
end
|
|
75
|
-
|
|
75
|
+
# if @scope has more than 2 ] then it's subform inside subform, and assign parent would fail (found associotion may be through association)
|
|
76
|
+
setup_parent(@record) if main_form_controller && @scope && @scope.scan(']').size == 2
|
|
76
77
|
after_render_field(@record, @column)
|
|
77
78
|
end
|
|
78
79
|
|
|
@@ -277,7 +278,9 @@ module ActiveScaffold::Actions
|
|
|
277
278
|
|
|
278
279
|
def new_model
|
|
279
280
|
relation = beginning_of_chain
|
|
280
|
-
|
|
281
|
+
if nested? && nested.plural_association? && nested.match_model?(active_scaffold_config.model)
|
|
282
|
+
build_options = sti_nested_build_options(relation.klass)
|
|
283
|
+
end
|
|
281
284
|
relation.respond_to?(:build) ? relation.build(build_options || {}) : relation.new
|
|
282
285
|
end
|
|
283
286
|
|
|
@@ -161,7 +161,7 @@ module ActiveScaffold::Actions
|
|
|
161
161
|
|
|
162
162
|
def count_query_on_association_class(column)
|
|
163
163
|
key = column.association.primary_key || :id
|
|
164
|
-
query = column.association.klass.where(column.association.foreign_key => @records.map(&key))
|
|
164
|
+
query = column.association.klass.where(column.association.foreign_key => @records.map(&key.to_sym))
|
|
165
165
|
if column.association.as
|
|
166
166
|
query.where!(column.association.reverse_association.foreign_type => active_scaffold_config.model.name)
|
|
167
167
|
end
|
|
@@ -90,7 +90,7 @@ module ActiveScaffold::Actions
|
|
|
90
90
|
|
|
91
91
|
def beginning_of_chain
|
|
92
92
|
# only if nested is related to current controller, e.g. not when adding record in subform inside subform
|
|
93
|
-
if nested? && nested.
|
|
93
|
+
if nested? && nested.match_model?(active_scaffold_config.model)
|
|
94
94
|
nested_chain_with_association
|
|
95
95
|
elsif nested? && nested.scope
|
|
96
96
|
nested_parent_record.send(nested.scope)
|
|
@@ -9,19 +9,25 @@ module ActiveScaffold::Actions
|
|
|
9
9
|
|
|
10
10
|
protected
|
|
11
11
|
|
|
12
|
-
def
|
|
13
|
-
|
|
14
|
-
if
|
|
15
|
-
|
|
16
|
-
|
|
12
|
+
def new_parent_record
|
|
13
|
+
parent_record = new_model
|
|
14
|
+
# don't apply if scope, subform inside subform, because constraints won't apply to parent_record
|
|
15
|
+
apply_constraints_to_record parent_record unless @scope
|
|
16
|
+
if nested? && nested.match_model?(active_scaffold_config.model)
|
|
17
|
+
create_association_with_parent parent_record
|
|
17
18
|
end
|
|
19
|
+
parent_record
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def do_edit_associated
|
|
23
|
+
@scope = params[:scope]
|
|
24
|
+
@parent_record = params[:id].nil? ? new_parent_record : find_if_allowed(params[:id], :update)
|
|
18
25
|
|
|
19
26
|
cache_generated_id(@parent_record, params[:generated_id]) if @parent_record.new_record?
|
|
20
27
|
@column = active_scaffold_config.columns[params[:child_association]]
|
|
21
28
|
|
|
22
29
|
@record = find_associated_record if params[:associated_id]
|
|
23
30
|
@record ||= build_associated(@column.association, @parent_record)
|
|
24
|
-
@scope = params[:scope]
|
|
25
31
|
end
|
|
26
32
|
|
|
27
33
|
def find_associated_record
|
|
@@ -230,7 +230,7 @@ module ActiveScaffold
|
|
|
230
230
|
return nil unless build_record_from_params?(attributes, column, parent_record)
|
|
231
231
|
record = find_or_create_for_params(attributes, column, parent_record)
|
|
232
232
|
if record
|
|
233
|
-
record_columns = active_scaffold_config_for(
|
|
233
|
+
record_columns = active_scaffold_config_for(record.class).subform.columns
|
|
234
234
|
prev_constraints = record_columns.constraint_columns
|
|
235
235
|
record_columns.constraint_columns = [column.association.reverse].compact
|
|
236
236
|
update_record_from_params(record, record_columns, attributes, avoid_changes)
|
|
@@ -242,8 +242,9 @@ module ActiveScaffold
|
|
|
242
242
|
|
|
243
243
|
def build_record_from_params?(params, column, record)
|
|
244
244
|
current = record.send(column.name)
|
|
245
|
-
|
|
246
|
-
|
|
245
|
+
return true if column.association.collection? && !column.show_blank_record?(current)
|
|
246
|
+
klass = column.association.klass(record)
|
|
247
|
+
klass && !attributes_hash_is_empty?(params, klass)
|
|
247
248
|
end
|
|
248
249
|
|
|
249
250
|
# Attempts to create or find an instance of the klass of the association in parent_column from the
|
|
@@ -251,12 +252,12 @@ module ActiveScaffold
|
|
|
251
252
|
# otherwise it will build a new one.
|
|
252
253
|
def find_or_create_for_params(params, parent_column, parent_record)
|
|
253
254
|
current = parent_record.send(parent_column.name)
|
|
254
|
-
klass = parent_column.association.klass
|
|
255
|
+
klass = parent_column.association.klass(parent_record)
|
|
255
256
|
if params.key? klass.primary_key
|
|
256
257
|
record_from_current_or_find(klass, params[klass.primary_key], current)
|
|
257
258
|
elsif klass.authorized_for?(:crud_type => :create)
|
|
258
259
|
association = parent_column.association
|
|
259
|
-
record =
|
|
260
|
+
record = klass.new
|
|
260
261
|
if association.reverse_association&.belongs_to? && (association.collection? || current.nil?)
|
|
261
262
|
record.send("#{parent_column.association.reverse}=", parent_record)
|
|
262
263
|
end
|
|
@@ -278,17 +279,6 @@ module ActiveScaffold
|
|
|
278
279
|
end
|
|
279
280
|
end
|
|
280
281
|
|
|
281
|
-
def save_record_to_association(record, association, value, reverse = nil)
|
|
282
|
-
return unless association
|
|
283
|
-
if association.collection?
|
|
284
|
-
record.send(association.name) << value
|
|
285
|
-
elsif reverse&.belongs_to?
|
|
286
|
-
value.send("#{reverse.name}=", record)
|
|
287
|
-
else
|
|
288
|
-
record.send("#{association.name}=", value)
|
|
289
|
-
end
|
|
290
|
-
end
|
|
291
|
-
|
|
292
282
|
# Determines whether the given attributes hash is "empty".
|
|
293
283
|
# This isn't a literal emptiness - it's an attempt to discern whether the user intended it to be empty or not.
|
|
294
284
|
def attributes_hash_is_empty?(hash, klass)
|
|
@@ -24,6 +24,7 @@ module ActiveScaffold
|
|
|
24
24
|
columns << field
|
|
25
25
|
columns.exclude "#{field}_attachment#{'s' if field_type == :has_many}".to_sym
|
|
26
26
|
columns.exclude "#{field}_blob#{'s' if field_type == :has_many}".to_sym
|
|
27
|
+
columns[field].includes ||= ["#{field}_attachment#{'s' if field_type == :has_many}".to_sym, "#{field}_blob#{'s' if field_type == :has_many}".to_sym]
|
|
27
28
|
columns[field].form_ui ||= "active_storage_#{field_type}".to_sym
|
|
28
29
|
columns[field].params.add "delete_#{field}"
|
|
29
30
|
end
|
|
@@ -3,7 +3,7 @@ module ActiveScaffold
|
|
|
3
3
|
module ListColumnHelpers
|
|
4
4
|
def active_scaffold_column_active_storage_has_one(record, column)
|
|
5
5
|
attachment = record.send(column.name.to_s)
|
|
6
|
-
attachment.attached? ? link_for_attachment(attachment) : nil
|
|
6
|
+
attachment.attached? ? link_for_attachment(attachment, column) : nil
|
|
7
7
|
end
|
|
8
8
|
|
|
9
9
|
def active_scaffold_column_active_storage_has_many(record, column)
|
|
@@ -12,7 +12,7 @@ module ActiveScaffold
|
|
|
12
12
|
|
|
13
13
|
attachments = active_storage_files.attachments
|
|
14
14
|
if attachments.size <= 3 # Lets display up to three links, otherwise just show the count.
|
|
15
|
-
links = attachments.map { |attachment| link_for_attachment(attachment) }
|
|
15
|
+
links = attachments.map { |attachment| link_for_attachment(attachment, column) }
|
|
16
16
|
safe_join links, association_join_text(column)
|
|
17
17
|
else
|
|
18
18
|
pluralize attachments.size, column.name.to_s
|
|
@@ -21,10 +21,10 @@ module ActiveScaffold
|
|
|
21
21
|
|
|
22
22
|
private
|
|
23
23
|
|
|
24
|
-
def link_for_attachment(attachment)
|
|
24
|
+
def link_for_attachment(attachment, column)
|
|
25
25
|
variant = column.options[:thumb] || ActiveScaffold::Bridges::ActiveStorage::ActiveStorageBridgeHelpers.thumbnail_variant
|
|
26
26
|
content =
|
|
27
|
-
if variant && attachment.variable?
|
|
27
|
+
if variant && attachment.variable? && column.options[:thumb] != false
|
|
28
28
|
image_tag(attachment.variant(variant))
|
|
29
29
|
else
|
|
30
30
|
attachment.filename
|