active_scaffold 3.4.43 → 3.5.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 +4 -4
- data/CHANGELOG +39 -0
- data/{LICENSE → LICENSE.md} +1 -1
- data/README.md +27 -19
- data/app/assets/javascripts/active_scaffold.js.erb +1 -1
- data/app/assets/javascripts/jquery/active_scaffold.js +95 -43
- data/app/assets/javascripts/jquery/tiny_mce_bridge.js +30 -6
- data/app/assets/javascripts/prototype/tiny_mce_bridge.js +11 -1
- data/app/assets/stylesheets/active_scaffold_colors.scss +2 -2
- data/app/assets/stylesheets/active_scaffold_layout.css +36 -28
- data/app/views/active_scaffold_overrides/_base_form.html.erb +2 -3
- data/app/views/active_scaffold_overrides/_field_search.html.erb +8 -7
- data/app/views/active_scaffold_overrides/_form_association.html.erb +9 -9
- data/app/views/active_scaffold_overrides/_form_association_footer.html.erb +6 -6
- data/app/views/active_scaffold_overrides/_form_association_record.html.erb +52 -50
- data/app/views/active_scaffold_overrides/_horizontal_subform.html.erb +1 -1
- data/app/views/active_scaffold_overrides/_horizontal_subform_header.html.erb +1 -1
- data/app/views/active_scaffold_overrides/_human_conditions.html.erb +3 -1
- data/app/views/active_scaffold_overrides/_list_calculations.html.erb +1 -1
- data/app/views/active_scaffold_overrides/_list_column_headings.html.erb +2 -0
- data/app/views/active_scaffold_overrides/_list_messages.html.erb +5 -3
- data/app/views/active_scaffold_overrides/_list_record.html.erb +3 -1
- data/app/views/active_scaffold_overrides/_list_with_header.html.erb +9 -9
- data/app/views/active_scaffold_overrides/_messages.html.erb +1 -1
- data/app/views/active_scaffold_overrides/_refresh_list.js.erb +18 -10
- data/app/views/active_scaffold_overrides/_render_field.js.erb +3 -3
- data/app/views/active_scaffold_overrides/_search.html.erb +7 -6
- data/app/views/active_scaffold_overrides/_show_actions.html.erb +14 -0
- data/app/views/active_scaffold_overrides/_show_association.html.erb +1 -1
- data/app/views/active_scaffold_overrides/_update_actions.html.erb +6 -2
- data/app/views/active_scaffold_overrides/_update_column.js.erb +1 -1
- data/app/views/active_scaffold_overrides/_update_form.html.erb +1 -1
- data/app/views/active_scaffold_overrides/destroy.js.erb +2 -3
- data/app/views/active_scaffold_overrides/edit_associated.js.erb +4 -3
- data/app/views/active_scaffold_overrides/on_action_update.js.erb +5 -3
- data/app/views/active_scaffold_overrides/on_create.js.erb +4 -4
- data/app/views/active_scaffold_overrides/on_update.js.erb +6 -6
- data/app/views/active_scaffold_overrides/show.html.erb +6 -0
- data/app/views/active_scaffold_overrides/update.html.erb +1 -1
- data/app/views/active_scaffold_overrides/update_column.js.erb +1 -1
- data/config/brakeman.ignore +26 -0
- data/config/brakeman.yml +3 -0
- data/config/i18n-tasks.yml +121 -0
- data/config/locales/de.yml +81 -70
- data/config/locales/en.yml +83 -74
- data/config/locales/es.yml +82 -73
- data/config/locales/fr.yml +86 -75
- data/config/locales/hu.yml +81 -70
- data/config/locales/ja.yml +71 -60
- data/config/locales/ru.yml +85 -74
- data/lib/active_scaffold.rb +3 -0
- data/lib/active_scaffold/actions/common_search.rb +11 -7
- data/lib/active_scaffold/actions/core.rb +119 -47
- data/lib/active_scaffold/actions/create.rb +1 -1
- data/lib/active_scaffold/actions/delete.rb +11 -8
- data/lib/active_scaffold/actions/field_search.rb +104 -6
- data/lib/active_scaffold/actions/list.rb +25 -21
- data/lib/active_scaffold/actions/mark.rb +12 -4
- data/lib/active_scaffold/actions/nested.rb +26 -26
- data/lib/active_scaffold/actions/search.rb +2 -2
- data/lib/active_scaffold/actions/show.rb +4 -5
- data/lib/active_scaffold/actions/subform.rb +9 -7
- data/lib/active_scaffold/actions/update.rb +20 -13
- data/lib/active_scaffold/active_record_permissions.rb +24 -5
- data/lib/active_scaffold/attribute_params.rb +68 -49
- data/lib/active_scaffold/bridges.rb +1 -1
- data/lib/active_scaffold/bridges/ancestry/ancestry_bridge.rb +15 -19
- data/lib/active_scaffold/bridges/bitfields.rb +1 -1
- data/lib/active_scaffold/bridges/bitfields/bitfields_bridge.rb +10 -14
- data/lib/active_scaffold/bridges/calendar_date_select.rb +0 -7
- data/lib/active_scaffold/bridges/calendar_date_select/as_cds_bridge.rb +19 -22
- data/lib/active_scaffold/bridges/cancan.rb +4 -3
- data/lib/active_scaffold/bridges/cancan/cancan_bridge.rb +11 -21
- data/lib/active_scaffold/bridges/carrierwave.rb +2 -1
- data/lib/active_scaffold/bridges/carrierwave/carrierwave_bridge.rb +2 -6
- data/lib/active_scaffold/bridges/carrierwave/form_ui.rb +6 -39
- data/lib/active_scaffold/bridges/carrierwave/list_ui.rb +1 -1
- data/lib/active_scaffold/bridges/chosen.rb +4 -1
- data/lib/active_scaffold/bridges/chosen/helpers.rb +3 -2
- data/lib/active_scaffold/bridges/country_select/country_select_bridge_helper.rb +2 -2
- data/lib/active_scaffold/bridges/date_picker.rb +3 -0
- data/lib/active_scaffold/bridges/date_picker/ext.rb +43 -38
- data/lib/active_scaffold/bridges/date_picker/helper.rb +24 -23
- data/lib/active_scaffold/bridges/dragonfly.rb +1 -1
- data/lib/active_scaffold/bridges/dragonfly/dragonfly_bridge.rb +3 -7
- data/lib/active_scaffold/bridges/dragonfly/form_ui.rb +3 -25
- data/lib/active_scaffold/bridges/dragonfly/list_ui.rb +2 -2
- data/lib/active_scaffold/bridges/file_column/as_file_column_bridge.rb +6 -8
- data/lib/active_scaffold/bridges/file_column/file_column_helpers.rb +1 -1
- data/lib/active_scaffold/bridges/file_column/form_ui.rb +0 -2
- data/lib/active_scaffold/bridges/file_column/list_ui.rb +2 -1
- data/lib/active_scaffold/bridges/file_column/test/test_helper.rb +1 -1
- data/lib/active_scaffold/bridges/paper_trail/actions.rb +1 -1
- data/lib/active_scaffold/bridges/paper_trail/helper.rb +1 -2
- data/lib/active_scaffold/bridges/paper_trail/paper_trail_bridge.rb +3 -7
- data/lib/active_scaffold/bridges/paperclip.rb +1 -1
- data/lib/active_scaffold/bridges/paperclip/form_ui.rb +3 -28
- data/lib/active_scaffold/bridges/paperclip/list_ui.rb +1 -1
- data/lib/active_scaffold/bridges/paperclip/paperclip_bridge.rb +3 -7
- data/lib/active_scaffold/bridges/record_select.rb +2 -0
- data/lib/active_scaffold/bridges/record_select/helpers.rb +14 -18
- data/lib/active_scaffold/bridges/semantic_attributes/column.rb +4 -8
- data/lib/active_scaffold/bridges/shared/date_bridge.rb +20 -20
- data/lib/active_scaffold/bridges/tiny_mce/helpers.rb +7 -22
- data/lib/active_scaffold/bridges/usa_state_select/usa_state_select_helper.rb +14 -14
- data/lib/active_scaffold/config/base.rb +9 -6
- data/lib/active_scaffold/config/core.rb +30 -21
- data/lib/active_scaffold/config/create.rb +2 -1
- data/lib/active_scaffold/config/delete.rb +2 -2
- data/lib/active_scaffold/config/field_search.rb +9 -3
- data/lib/active_scaffold/config/form.rb +4 -4
- data/lib/active_scaffold/config/list.rb +27 -23
- data/lib/active_scaffold/config/nested.rb +4 -4
- data/lib/active_scaffold/config/search.rb +6 -6
- data/lib/active_scaffold/config/show.rb +11 -1
- data/lib/active_scaffold/config/subform.rb +1 -1
- data/lib/active_scaffold/config/update.rb +4 -2
- data/lib/active_scaffold/constraints.rb +39 -36
- data/lib/active_scaffold/core.rb +36 -15
- data/lib/active_scaffold/data_structures/action_columns.rb +14 -9
- data/lib/active_scaffold/data_structures/action_link.rb +4 -5
- data/lib/active_scaffold/data_structures/action_links.rb +5 -4
- data/lib/active_scaffold/data_structures/actions.rb +2 -2
- data/lib/active_scaffold/data_structures/association.rb +8 -0
- data/lib/active_scaffold/data_structures/association/abstract.rb +147 -0
- data/lib/active_scaffold/data_structures/association/active_mongoid.rb +42 -0
- data/lib/active_scaffold/data_structures/association/active_record.rb +94 -0
- data/lib/active_scaffold/data_structures/association/mongoid.rb +45 -0
- data/lib/active_scaffold/data_structures/bridge.rb +3 -6
- data/lib/active_scaffold/data_structures/column.rb +100 -82
- data/lib/active_scaffold/data_structures/columns.rb +21 -3
- data/lib/active_scaffold/data_structures/nested_info.rb +22 -37
- data/lib/active_scaffold/data_structures/set.rb +4 -4
- data/lib/active_scaffold/data_structures/sorting.rb +29 -15
- data/lib/active_scaffold/engine.rb +3 -1
- data/lib/active_scaffold/extensions/action_controller_rendering.rb +10 -5
- data/lib/active_scaffold/extensions/action_view_rendering.rb +65 -59
- data/lib/active_scaffold/extensions/left_outer_joins.rb +48 -53
- data/lib/active_scaffold/extensions/localize.rb +3 -4
- data/lib/active_scaffold/extensions/name_option_for_datetime.rb +7 -11
- data/lib/active_scaffold/extensions/paginator_extensions.rb +20 -18
- data/lib/active_scaffold/extensions/routing_mapper.rb +104 -40
- data/lib/active_scaffold/extensions/to_label.rb +1 -1
- data/lib/active_scaffold/extensions/unsaved_associated.rb +4 -13
- data/lib/active_scaffold/extensions/unsaved_record.rb +12 -1
- data/lib/active_scaffold/finder.rb +200 -134
- data/lib/active_scaffold/helpers/action_link_helpers.rb +398 -0
- data/lib/active_scaffold/helpers/association_helpers.rb +12 -30
- data/lib/active_scaffold/helpers/controller_helpers.rb +74 -24
- data/lib/active_scaffold/helpers/form_column_helpers.rb +205 -112
- data/lib/active_scaffold/helpers/human_condition_helpers.rb +21 -11
- data/lib/active_scaffold/helpers/id_helpers.rb +1 -1
- data/lib/active_scaffold/helpers/list_column_helpers.rb +117 -39
- data/lib/active_scaffold/helpers/pagination_helpers.rb +11 -14
- data/lib/active_scaffold/helpers/search_column_helpers.rb +69 -32
- data/lib/active_scaffold/helpers/show_column_helpers.rb +9 -3
- data/lib/active_scaffold/helpers/view_helpers.rb +41 -426
- data/lib/active_scaffold/orm_checks.rb +109 -0
- data/lib/active_scaffold/paginator.rb +1 -1
- data/lib/active_scaffold/responds_to_parent.rb +12 -10
- data/lib/active_scaffold/tableless.rb +81 -43
- data/lib/active_scaffold/version.rb +2 -2
- data/lib/generators/active_scaffold/controller_generator.rb +49 -0
- data/lib/generators/active_scaffold/install_generator.rb +45 -0
- data/lib/generators/active_scaffold/resource_generator.rb +56 -0
- data/lib/generators/{active_scaffold_controller/templates → templates}/controller.rb +0 -0
- data/lib/generators/{active_scaffold_controller/templates → templates}/helper.rb +0 -0
- data/shoulda_macros/macros.rb +3 -3
- data/test/active_scaffold_config_mock.rb +33 -0
- data/test/bridges/bridge_test.rb +9 -9
- data/test/bridges/date_picker_test.rb +3 -1
- data/test/bridges/paper_trail_test.rb +2 -3
- data/test/bridges/paperclip_test.rb +21 -10
- data/test/bridges/tiny_mce_test.rb +20 -21
- data/test/class_with_finder.rb +42 -0
- data/test/company.rb +6 -4
- data/test/config/core_test.rb +1 -1
- data/test/config/create_test.rb +1 -1
- data/test/config/list_test.rb +3 -3
- data/test/config/update_test.rb +3 -3
- data/test/data_structures/action_columns_test.rb +3 -3
- data/test/data_structures/association_column_test.rb +5 -5
- data/test/data_structures/column_test.rb +14 -14
- data/test/data_structures/columns_test.rb +2 -2
- data/test/data_structures/set_test.rb +2 -2
- data/test/data_structures/sorting_test.rb +6 -4
- data/test/extensions/active_record_test.rb +1 -1
- data/test/extensions/routing_mapper_test.rb +64 -13
- data/test/helpers/form_column_helpers_test.rb +6 -6
- data/test/helpers/list_column_helpers_test.rb +9 -5
- data/test/helpers/pagination_helpers_test.rb +1 -0
- data/test/misc/active_record_permissions_test.rb +18 -1
- data/test/misc/attribute_params_test.rb +26 -17
- data/test/misc/calculation_test.rb +8 -31
- data/test/misc/configurable_test.rb +3 -2
- data/test/misc/constraints_test.rb +33 -22
- data/test/misc/convert_numbers_format_test.rb +28 -10
- data/test/misc/finder_test.rb +6 -29
- data/test/misc/parse_datetime_test.rb +160 -0
- data/test/misc/render_test.rb +1 -1
- data/test/misc/tableless_test.rb +24 -0
- data/test/mock_app/app/models/building.rb +2 -1
- data/test/mock_app/config.ru +1 -1
- data/test/mock_app/config/environments/test.rb +1 -1
- data/test/mock_app/config/routes.rb +11 -3
- data/test/model_stub.rb +11 -6
- data/test/run_all.rb +1 -1
- data/test/test_helper.rb +19 -4
- metadata +42 -23
- data/lib/active_scaffold/data_structures/error_message.rb +0 -22
- data/lib/active_scaffold/extensions/reverse_associations.rb +0 -119
- data/lib/generators/active_scaffold/USAGE +0 -29
- data/lib/generators/active_scaffold/active_scaffold_generator.rb +0 -21
- data/lib/generators/active_scaffold_controller/USAGE +0 -19
- data/lib/generators/active_scaffold_controller/active_scaffold_controller_generator.rb +0 -29
- data/test/data_structures/error_message_test.rb +0 -25
| @@ -13,13 +13,14 @@ module ActiveScaffold::Config | |
| 13 13 | 
             
                def self.link
         | 
| 14 14 | 
             
                  @@link
         | 
| 15 15 | 
             
                end
         | 
| 16 | 
            +
             | 
| 16 17 | 
             
                def self.link=(val)
         | 
| 17 18 | 
             
                  @@link = val
         | 
| 18 19 | 
             
                end
         | 
| 19 20 | 
             
                @@link = ActiveScaffold::DataStructures::ActionLink.new('new', :label => :create_new, :type => :collection, :security_method => :create_authorized?, :ignore_method => :create_ignore?)
         | 
| 20 21 |  | 
| 21 22 | 
             
                # whether update form is opened after a create or not
         | 
| 22 | 
            -
                cattr_accessor :action_after_create
         | 
| 23 | 
            +
                cattr_accessor :action_after_create, instance_accessor: false
         | 
| 23 24 | 
             
                @@action_after_create = nil
         | 
| 24 25 |  | 
| 25 26 | 
             
                # instance-level configuration
         | 
| @@ -11,11 +11,11 @@ module ActiveScaffold::Config | |
| 11 11 | 
             
                # --------------------------
         | 
| 12 12 |  | 
| 13 13 | 
             
                # the ActionLink for this action
         | 
| 14 | 
            -
                cattr_accessor :link
         | 
| 14 | 
            +
                cattr_accessor :link, instance_accessor: false
         | 
| 15 15 | 
             
                @@link = ActiveScaffold::DataStructures::ActionLink.new('destroy', :label => :delete, :type => :member, :confirm => :are_you_sure_to_delete, :method => :delete, :crud_type => :delete, :position => false, :parameters => {:destroy_action => true}, :security_method => :delete_authorized?, :ignore_method => :delete_ignore?)
         | 
| 16 16 |  | 
| 17 17 | 
             
                # whether we should refresh list after destroy or not
         | 
| 18 | 
            -
                cattr_accessor :refresh_list
         | 
| 18 | 
            +
                cattr_accessor :refresh_list, instance_accessor: false
         | 
| 19 19 | 
             
                @@refresh_list = false
         | 
| 20 20 |  | 
| 21 21 | 
             
                # instance-level configuration
         | 
| @@ -11,7 +11,7 @@ module ActiveScaffold::Config | |
| 11 11 | 
             
                # global level configuration
         | 
| 12 12 | 
             
                # --------------------------
         | 
| 13 13 | 
             
                # the ActionLink for this action
         | 
| 14 | 
            -
                cattr_reader :link
         | 
| 14 | 
            +
                cattr_reader :link, instance_accessor: false
         | 
| 15 15 | 
             
                @@link = ActiveScaffold::DataStructures::ActionLink.new('show_search', :label => :search, :type => :collection, :security_method => :search_authorized?, :ignore_method => :field_search_ignore?)
         | 
| 16 16 |  | 
| 17 17 | 
             
                # A flag for how the search should do full-text searching in the database:
         | 
| @@ -20,12 +20,12 @@ module ActiveScaffold::Config | |
| 20 20 | 
             
                # * :end: LIKE %?
         | 
| 21 21 | 
             
                # * false: LIKE ?
         | 
| 22 22 | 
             
                # Default is :full
         | 
| 23 | 
            -
                cattr_accessor :text_search
         | 
| 23 | 
            +
                cattr_accessor :text_search, instance_accessor: false
         | 
| 24 24 | 
             
                @@text_search = :full
         | 
| 25 25 |  | 
| 26 26 | 
             
                # human conditions
         | 
| 27 27 | 
             
                # instead of just filtered you may show the user a humanized search condition statment
         | 
| 28 | 
            -
                cattr_accessor :human_conditions
         | 
| 28 | 
            +
                cattr_accessor :human_conditions, instance_accessor: false
         | 
| 29 29 | 
             
                @@human_conditions = false
         | 
| 30 30 |  | 
| 31 31 | 
             
                # instance-level configuration
         | 
| @@ -55,6 +55,12 @@ module ActiveScaffold::Config | |
| 55 55 | 
             
                  @optional_columns ||= []
         | 
| 56 56 | 
             
                end
         | 
| 57 57 |  | 
| 58 | 
            +
                # add array of columns as options for group by to get aggregated listings
         | 
| 59 | 
            +
                attr_accessor :group_options
         | 
| 60 | 
            +
             | 
| 61 | 
            +
                # columns to display on aggregated listing
         | 
| 62 | 
            +
                attr_accessor :grouped_columns
         | 
| 63 | 
            +
             | 
| 58 64 | 
             
                # default search params
         | 
| 59 65 | 
             
                # default_params = {:title => {"from"=>"test", "to"=>"", "opt"=>"%?%"}}
         | 
| 60 66 | 
             
                attr_accessor :default_params
         | 
| @@ -13,14 +13,14 @@ module ActiveScaffold::Config | |
| 13 13 | 
             
                # global level configuration
         | 
| 14 14 | 
             
                # --------------------------
         | 
| 15 15 | 
             
                # show value of unauthorized columns instead of skip them
         | 
| 16 | 
            -
                class_attribute :show_unauthorized_columns
         | 
| 16 | 
            +
                class_attribute :show_unauthorized_columns, instance_accessor: false
         | 
| 17 17 |  | 
| 18 18 | 
             
                # whether the form stays open after an update or not
         | 
| 19 | 
            -
                 | 
| 19 | 
            +
                class_attribute :persistent, instance_accessor: false
         | 
| 20 20 | 
             
                @@persistent = false
         | 
| 21 21 |  | 
| 22 22 | 
             
                # whether we should refresh list after update or not
         | 
| 23 | 
            -
                 | 
| 23 | 
            +
                class_attribute :refresh_list, instance_accessor: false
         | 
| 24 24 | 
             
                @@refresh_list = false
         | 
| 25 25 |  | 
| 26 26 | 
             
                # instance-level configuration
         | 
| @@ -43,7 +43,7 @@ module ActiveScaffold::Config | |
| 43 43 |  | 
| 44 44 | 
             
                columns_accessor :columns do
         | 
| 45 45 | 
             
                  columns.exclude :created_on, :created_at, :updated_on, :updated_at, :as_marked
         | 
| 46 | 
            -
                  columns.exclude | 
| 46 | 
            +
                  columns.exclude(*@core.columns.collect { |c| c.name if c.association.try(:polymorphic?) }.compact)
         | 
| 47 47 | 
             
                end
         | 
| 48 48 |  | 
| 49 49 | 
             
                # whether the form should be multipart
         | 
| @@ -11,8 +11,8 @@ module ActiveScaffold::Config | |
| 11 11 | 
             
                  @page_links_outer_window = self.class.page_links_outer_window
         | 
| 12 12 |  | 
| 13 13 | 
             
                  # originates here
         | 
| 14 | 
            -
                  @sorting = ActiveScaffold::DataStructures::Sorting.new(@core.columns)
         | 
| 15 | 
            -
                  @sorting.set_default_sorting | 
| 14 | 
            +
                  @sorting = ActiveScaffold::DataStructures::Sorting.new(@core.columns, @core.model)
         | 
| 15 | 
            +
                  @sorting.set_default_sorting
         | 
| 16 16 |  | 
| 17 17 | 
             
                  # inherit from global scope
         | 
| 18 18 | 
             
                  @empty_field_text = self.class.empty_field_text
         | 
| @@ -33,74 +33,74 @@ module ActiveScaffold::Config | |
| 33 33 | 
             
                # global level configuration
         | 
| 34 34 | 
             
                # --------------------------
         | 
| 35 35 | 
             
                # include list header on refresh
         | 
| 36 | 
            -
                cattr_accessor :refresh_with_header
         | 
| 36 | 
            +
                cattr_accessor :refresh_with_header, instance_accessor: false
         | 
| 37 37 | 
             
                @@refresh_with_header = false
         | 
| 38 38 |  | 
| 39 39 | 
             
                # how many records to show per page
         | 
| 40 | 
            -
                cattr_accessor :per_page
         | 
| 40 | 
            +
                cattr_accessor :per_page, instance_accessor: false
         | 
| 41 41 | 
             
                @@per_page = 15
         | 
| 42 42 |  | 
| 43 43 | 
             
                # how many page links around current page to show
         | 
| 44 | 
            -
                cattr_accessor :page_links_inner_window
         | 
| 44 | 
            +
                cattr_accessor :page_links_inner_window, instance_accessor: false
         | 
| 45 45 | 
             
                @@page_links_inner_window = 2
         | 
| 46 46 |  | 
| 47 47 | 
             
                # how many page links around first and last page to show
         | 
| 48 | 
            -
                cattr_accessor :page_links_outer_window
         | 
| 48 | 
            +
                cattr_accessor :page_links_outer_window, instance_accessor: false
         | 
| 49 49 | 
             
                @@page_links_outer_window = 0
         | 
| 50 50 |  | 
| 51 51 | 
             
                # what string to use when a field is empty
         | 
| 52 | 
            -
                cattr_accessor :empty_field_text
         | 
| 52 | 
            +
                cattr_accessor :empty_field_text, instance_accessor: false
         | 
| 53 53 | 
             
                @@empty_field_text = '-'
         | 
| 54 54 |  | 
| 55 55 | 
             
                # display messages above table header
         | 
| 56 | 
            -
                cattr_accessor :messages_above_header
         | 
| 56 | 
            +
                cattr_accessor :messages_above_header, instance_accessor: false
         | 
| 57 57 | 
             
                @@messages_above_header = false
         | 
| 58 58 |  | 
| 59 59 | 
             
                # what string to use to join records from plural associations
         | 
| 60 | 
            -
                cattr_accessor :association_join_text
         | 
| 60 | 
            +
                cattr_accessor :association_join_text, instance_accessor: false
         | 
| 61 61 | 
             
                @@association_join_text = ', '
         | 
| 62 62 |  | 
| 63 63 | 
             
                # What kind of pagination to use:
         | 
| 64 64 | 
             
                # * true: The usual pagination
         | 
| 65 65 | 
             
                # * :infinite: Treat the source as having an infinite number of pages (i.e. don't count the records; useful for large tables where counting is slow and we don't really care anyway)
         | 
| 66 66 | 
             
                # * false: Disable pagination
         | 
| 67 | 
            -
                cattr_accessor :pagination
         | 
| 67 | 
            +
                cattr_accessor :pagination, instance_accessor: false
         | 
| 68 68 | 
             
                @@pagination = true
         | 
| 69 69 |  | 
| 70 70 | 
             
                # Auto paginate, only can be used with pagination enabled
         | 
| 71 71 | 
             
                # * true: First page will be loaded on first request, next pages will be requested by AJAX until all items are loaded
         | 
| 72 72 | 
             
                # * false: Disable auto pagination
         | 
| 73 | 
            -
                cattr_accessor :auto_pagination
         | 
| 73 | 
            +
                cattr_accessor :auto_pagination, instance_accessor: false
         | 
| 74 74 | 
             
                @@auto_pagination = false
         | 
| 75 75 |  | 
| 76 76 | 
             
                # show a link to reset the search next to filtered message
         | 
| 77 | 
            -
                cattr_accessor :show_search_reset
         | 
| 77 | 
            +
                cattr_accessor :show_search_reset, instance_accessor: false
         | 
| 78 78 | 
             
                @@show_search_reset = true
         | 
| 79 79 |  | 
| 80 80 | 
             
                # the ActionLink to reset search
         | 
| 81 | 
            -
                cattr_reader :reset_link
         | 
| 81 | 
            +
                cattr_reader :reset_link, instance_reader: false
         | 
| 82 82 | 
             
                @@reset_link = ActiveScaffold::DataStructures::ActionLink.new('index', :label => :click_to_reset, :type => :collection, :position => false, :parameters => {:search => ''})
         | 
| 83 83 |  | 
| 84 84 | 
             
                # wrap normal cells (not inplace editable columns or with link) with a tag
         | 
| 85 85 | 
             
                # it allows for more css styling
         | 
| 86 | 
            -
                cattr_accessor :wrap_tag
         | 
| 86 | 
            +
                cattr_accessor :wrap_tag, instance_accessor: false
         | 
| 87 87 | 
             
                @@wrap_tag = nil
         | 
| 88 88 |  | 
| 89 89 | 
             
                # Show search form in the list header instead of display the link
         | 
| 90 | 
            -
                cattr_accessor :always_show_search
         | 
| 90 | 
            +
                cattr_accessor :always_show_search, instance_accessor: false
         | 
| 91 91 | 
             
                @@always_show_search = false
         | 
| 92 92 |  | 
| 93 93 | 
             
                # Show create form in the list header instead of display the link
         | 
| 94 | 
            -
                cattr_accessor :always_show_create
         | 
| 94 | 
            +
                cattr_accessor :always_show_create, instance_accessor: false
         | 
| 95 95 | 
             
                @@always_show_create = false
         | 
| 96 96 |  | 
| 97 97 | 
             
                # Enable auto select columns on list, so only columns needed for list columns are selected
         | 
| 98 | 
            -
                cattr_accessor :auto_select_columns
         | 
| 98 | 
            +
                cattr_accessor :auto_select_columns, instance_accessor: false
         | 
| 99 99 | 
             
                @@auto_select_columns = false
         | 
| 100 100 |  | 
| 101 101 | 
             
                # Enable ETag calculation (when conditional_get_support is enabled), it requires to load records for page, when is disabled query can be avoided when page is cached in browser
         | 
| 102 102 | 
             
                # order clause will be used for ETag when calculate_etag is disabled, so query for records can be avoided
         | 
| 103 | 
            -
                cattr_accessor :calculate_etag
         | 
| 103 | 
            +
                cattr_accessor :calculate_etag, instance_accessor: false
         | 
| 104 104 | 
             
                @@calculate_etag = false
         | 
| 105 105 |  | 
| 106 106 | 
             
                # instance-level configuration
         | 
| @@ -152,11 +152,11 @@ module ActiveScaffold::Config | |
| 152 152 | 
             
                # to just sort on one column, you can simply provide a hash, e.g. {:a => 'desc'}.
         | 
| 153 153 | 
             
                def sorting=(val)
         | 
| 154 154 | 
             
                  val = [val] if val.is_a? Hash
         | 
| 155 | 
            -
                  sorting.set | 
| 155 | 
            +
                  sorting.set(*val)
         | 
| 156 156 | 
             
                end
         | 
| 157 157 |  | 
| 158 158 | 
             
                def sorting
         | 
| 159 | 
            -
                  @sorting ||= ActiveScaffold::DataStructures::Sorting.new(@core.columns)
         | 
| 159 | 
            +
                  @sorting ||= ActiveScaffold::DataStructures::Sorting.new(@core.columns, @core.model)
         | 
| 160 160 | 
             
                end
         | 
| 161 161 |  | 
| 162 162 | 
             
                # overwrite the includes used for the count sql query
         | 
| @@ -180,7 +180,7 @@ module ActiveScaffold::Config | |
| 180 180 |  | 
| 181 181 | 
             
                attr_writer :always_show_search
         | 
| 182 182 | 
             
                def always_show_search
         | 
| 183 | 
            -
                  @always_show_search &&  | 
| 183 | 
            +
                  @always_show_search && search_partial.present?
         | 
| 184 184 | 
             
                end
         | 
| 185 185 |  | 
| 186 186 | 
             
                def search_partial
         | 
| @@ -228,7 +228,11 @@ module ActiveScaffold::Config | |
| 228 228 | 
             
                  attr_writer :label
         | 
| 229 229 | 
             
                  # This label has already been localized.
         | 
| 230 230 | 
             
                  def label
         | 
| 231 | 
            -
                    self['label'] || @label || @conf.label
         | 
| 231 | 
            +
                    self['label'] || embedded_label || @label || @conf.label
         | 
| 232 | 
            +
                  end
         | 
| 233 | 
            +
             | 
| 234 | 
            +
                  def embedded_label
         | 
| 235 | 
            +
                    @params[:embedded][:label] if @params[:embedded]
         | 
| 232 236 | 
             
                  end
         | 
| 233 237 |  | 
| 234 238 | 
             
                  def per_page
         | 
| @@ -266,7 +270,7 @@ module ActiveScaffold::Config | |
| 266 270 | 
             
                      self['sort'] = [@params['sort'], @params['sort_direction']] if @params['sort'] && @params['sort_direction']
         | 
| 267 271 | 
             
                      self['sort'] = nil if @params['sort_direction'] == 'reset'
         | 
| 268 272 |  | 
| 269 | 
            -
                      if self['sort']
         | 
| 273 | 
            +
                      if self['sort'] && @conf.core.columns[self['sort'][0]]
         | 
| 270 274 | 
             
                        sorting = @conf.sorting.clone
         | 
| 271 275 | 
             
                        sorting.set(*self['sort'])
         | 
| 272 276 | 
             
                        @sorting = sorting
         | 
| @@ -11,10 +11,10 @@ module ActiveScaffold::Config | |
| 11 11 |  | 
| 12 12 | 
             
                # global level configuration
         | 
| 13 13 | 
             
                # --------------------------
         | 
| 14 | 
            -
                cattr_accessor :shallow_delete
         | 
| 14 | 
            +
                cattr_accessor :shallow_delete, instance_accessor: false
         | 
| 15 15 | 
             
                @@shallow_delete = true
         | 
| 16 16 |  | 
| 17 | 
            -
                cattr_accessor :ignore_order_from_association
         | 
| 17 | 
            +
                cattr_accessor :ignore_order_from_association, instance_accessor: false
         | 
| 18 18 |  | 
| 19 19 | 
             
                # instance-level configuration
         | 
| 20 20 | 
             
                # ----------------------------
         | 
| @@ -27,10 +27,10 @@ module ActiveScaffold::Config | |
| 27 27 | 
             
                  column = @core.columns[attribute.to_sym]
         | 
| 28 28 | 
             
                  if column && column.association
         | 
| 29 29 | 
             
                    label =
         | 
| 30 | 
            -
                      if column. | 
| 30 | 
            +
                      if column.association.polymorphic?
         | 
| 31 31 | 
             
                        column.label
         | 
| 32 32 | 
             
                      else
         | 
| 33 | 
            -
                        column.association.klass.model_name.human(:count => column. | 
| 33 | 
            +
                        column.association.klass.model_name.human(:count => column.association.singular? ? 1 : 2, :default => column.association.klass.name.pluralize)
         | 
| 34 34 | 
             
                      end
         | 
| 35 35 | 
             
                    options.reverse_merge! :security_method => :nested_authorized?, :label => label
         | 
| 36 36 | 
             
                    action_group = options.delete(:action_group) || self.action_group
         | 
| @@ -12,7 +12,7 @@ module ActiveScaffold::Config | |
| 12 12 | 
             
                # global level configuration
         | 
| 13 13 | 
             
                # --------------------------
         | 
| 14 14 | 
             
                # the ActionLink for this action
         | 
| 15 | 
            -
                cattr_accessor :link
         | 
| 15 | 
            +
                cattr_accessor :link, instance_accessor: false
         | 
| 16 16 | 
             
                @@link = ActiveScaffold::DataStructures::ActionLink.new('show_search', :label => :search, :type => :collection, :security_method => :search_authorized?, :ignore_method => :search_ignore?)
         | 
| 17 17 |  | 
| 18 18 | 
             
                # A flag for how the search should do full-text searching in the database:
         | 
| @@ -21,30 +21,30 @@ module ActiveScaffold::Config | |
| 21 21 | 
             
                # * :end: LIKE %?
         | 
| 22 22 | 
             
                # * false: LIKE ?
         | 
| 23 23 | 
             
                # Default is :full
         | 
| 24 | 
            -
                cattr_accessor :text_search
         | 
| 24 | 
            +
                cattr_accessor :text_search, instance_accessor: false
         | 
| 25 25 | 
             
                @@text_search = :full
         | 
| 26 26 |  | 
| 27 27 | 
             
                # whether submits the search as you type
         | 
| 28 | 
            -
                cattr_writer :live
         | 
| 28 | 
            +
                cattr_writer :live, instance_writer: false
         | 
| 29 29 | 
             
                def self.live?
         | 
| 30 30 | 
             
                  @@live
         | 
| 31 31 | 
             
                end
         | 
| 32 32 |  | 
| 33 | 
            -
                cattr_accessor :split_terms
         | 
| 33 | 
            +
                cattr_accessor :split_terms, instance_accessor: false
         | 
| 34 34 | 
             
                @@split_terms = ' '
         | 
| 35 35 |  | 
| 36 36 | 
             
                # instance-level configuration
         | 
| 37 37 | 
             
                # ----------------------------
         | 
| 38 38 |  | 
| 39 | 
            -
                columns_accessor :columns
         | 
| 40 39 | 
             
                # provides access to the list of columns specifically meant for the Search to use
         | 
| 41 40 | 
             
                def columns
         | 
| 42 41 | 
             
                  # we want to delay initializing to the @core.columns set for as long as possible. Too soon and .search_sql will not be available to .searchable?
         | 
| 43 | 
            -
                  unless @columns
         | 
| 42 | 
            +
                  unless defined? @columns
         | 
| 44 43 | 
             
                    self.columns = @core.columns.collect { |c| c.name if @core.columns._inheritable.include?(c.name) && c.searchable? && c.association.nil? && c.text? }.compact
         | 
| 45 44 | 
             
                  end
         | 
| 46 45 | 
             
                  @columns
         | 
| 47 46 | 
             
                end
         | 
| 47 | 
            +
                columns_accessor :columns
         | 
| 48 48 |  | 
| 49 49 | 
             
                # A flag for how the search should do full-text searching in the database:
         | 
| 50 50 | 
             
                # * :full: LIKE %?%
         | 
| @@ -1,14 +1,24 @@ | |
| 1 1 | 
             
            module ActiveScaffold::Config
         | 
| 2 2 | 
             
              class Show < Base
         | 
| 3 3 | 
             
                self.crud_type = :read
         | 
| 4 | 
            +
                def initialize(core_config)
         | 
| 5 | 
            +
                  super
         | 
| 6 | 
            +
                  self.inline_links = self.class.inline_links
         | 
| 7 | 
            +
                end
         | 
| 4 8 |  | 
| 5 9 | 
             
                # global level configuration
         | 
| 6 10 | 
             
                # --------------------------
         | 
| 7 | 
            -
                cattr_accessor :link
         | 
| 11 | 
            +
                cattr_accessor :link, instance_accessor: false
         | 
| 8 12 | 
             
                @@link = ActiveScaffold::DataStructures::ActionLink.new('show', :label => :show, :type => :member, :security_method => :show_authorized?, :ignore_method => :show_ignore?)
         | 
| 13 | 
            +
             | 
| 14 | 
            +
                cattr_accessor :inline_links, instance_accessor: false
         | 
| 15 | 
            +
                @@inline_links = false
         | 
| 16 | 
            +
             | 
| 9 17 | 
             
                # instance-level configuration
         | 
| 10 18 | 
             
                # ----------------------------
         | 
| 11 19 |  | 
| 20 | 
            +
                attr_accessor :inline_links
         | 
| 21 | 
            +
             | 
| 12 22 | 
             
                # the ActionLink for this action
         | 
| 13 23 | 
             
                attr_accessor :link
         | 
| 14 24 | 
             
                # the label for this action. used for the header.
         | 
| @@ -12,19 +12,21 @@ module ActiveScaffold::Config | |
| 12 12 | 
             
                def self.link
         | 
| 13 13 | 
             
                  @@link
         | 
| 14 14 | 
             
                end
         | 
| 15 | 
            +
             | 
| 15 16 | 
             
                def self.link=(val)
         | 
| 16 17 | 
             
                  @@link = val
         | 
| 17 18 | 
             
                end
         | 
| 18 19 | 
             
                @@link = ActiveScaffold::DataStructures::ActionLink.new('edit', :label => :edit, :type => :member, :security_method => :update_authorized?, :ignore_method => :update_ignore?)
         | 
| 19 20 |  | 
| 21 | 
            +
                cattr_accessor :nested_links, instance_accessor: false
         | 
| 22 | 
            +
                @@nested_links = false
         | 
| 23 | 
            +
             | 
| 20 24 | 
             
                columns_accessor :columns, :copy => :create
         | 
| 21 25 |  | 
| 22 26 | 
             
                # instance-level configuration
         | 
| 23 27 | 
             
                # ----------------------------
         | 
| 24 28 |  | 
| 25 29 | 
             
                attr_accessor :nested_links
         | 
| 26 | 
            -
                cattr_accessor :nested_links
         | 
| 27 | 
            -
                @@nested_links = false
         | 
| 28 30 |  | 
| 29 31 | 
             
                attr_writer :hide_nested_column
         | 
| 30 32 | 
             
                def hide_nested_column
         | 
| @@ -8,7 +8,7 @@ module ActiveScaffold | |
| 8 8 |  | 
| 9 9 | 
             
                # Returns the current constraints
         | 
| 10 10 | 
             
                def active_scaffold_constraints
         | 
| 11 | 
            -
                  @active_scaffold_constraints ||=  | 
| 11 | 
            +
                  @active_scaffold_constraints ||= active_scaffold_embedded_params[:constraints] || {}
         | 
| 12 12 | 
             
                end
         | 
| 13 13 |  | 
| 14 14 | 
             
                # For each enabled action, adds the constrained columns to the ActionColumns object (if it exists).
         | 
| @@ -17,9 +17,9 @@ module ActiveScaffold | |
| 17 17 | 
             
                # If the constraint value is a Hash, then we assume the constraint is a multi-level association constraint (the reverse of a has_many :through) and we do NOT register the constraint column.
         | 
| 18 18 | 
             
                def register_constraints_with_action_columns(constrained_fields = nil)
         | 
| 19 19 | 
             
                  constrained_fields ||= []
         | 
| 20 | 
            -
                  constrained_fields |= active_scaffold_constraints.reject { |_, v| v | 
| 20 | 
            +
                  constrained_fields |= active_scaffold_constraints.reject { |_, v| params_hash?(v) }.keys.collect(&:to_sym)
         | 
| 21 21 | 
             
                  exclude_actions = []
         | 
| 22 | 
            -
                  [ | 
| 22 | 
            +
                  %i[list update].each do |action_name|
         | 
| 23 23 | 
             
                    if active_scaffold_config.actions.include? action_name
         | 
| 24 24 | 
             
                      exclude_actions << action_name unless active_scaffold_config.send(action_name).hide_nested_column
         | 
| 25 25 | 
             
                    end
         | 
| @@ -51,26 +51,26 @@ module ActiveScaffold | |
| 51 51 | 
             
                      # example:
         | 
| 52 52 | 
             
                      #   data model: Park -> Den -> Bear
         | 
| 53 53 | 
             
                      #   constraint: :den => {:park => 5}
         | 
| 54 | 
            -
                      if  | 
| 54 | 
            +
                      if params_hash? v
         | 
| 55 55 | 
             
                        far_association = column.association.klass.reflect_on_association(v.keys.first)
         | 
| 56 56 | 
             
                        field = far_association.klass.primary_key
         | 
| 57 57 | 
             
                        table = far_association.table_name
         | 
| 58 58 |  | 
| 59 59 | 
             
                        active_scaffold_references.concat([{k => far_association.name}]) # e.g. {:den => :park}
         | 
| 60 | 
            -
                        hash_conditions. | 
| 60 | 
            +
                        hash_conditions.deep_merge!(table => {field => v.values.first})
         | 
| 61 61 |  | 
| 62 62 | 
             
                      # association column constraint
         | 
| 63 63 | 
             
                      elsif column.association
         | 
| 64 | 
            -
                        if column.association. | 
| 64 | 
            +
                        if column.association.habtm?
         | 
| 65 65 | 
             
                          active_scaffold_habtm_joins.concat column.includes
         | 
| 66 | 
            -
                        elsif !column.association. | 
| 67 | 
            -
                          if column.association. | 
| 66 | 
            +
                        elsif !column.association.polymorphic?
         | 
| 67 | 
            +
                          if column.association.belongs_to?
         | 
| 68 68 | 
             
                            active_scaffold_preload.concat column.includes
         | 
| 69 69 | 
             
                          else
         | 
| 70 70 | 
             
                            active_scaffold_references.concat column.includes
         | 
| 71 71 | 
             
                          end
         | 
| 72 72 | 
             
                        end
         | 
| 73 | 
            -
                        hash_conditions. | 
| 73 | 
            +
                        hash_conditions.deep_merge!(condition_from_association_constraint(column.association, v))
         | 
| 74 74 |  | 
| 75 75 | 
             
                      # regular column constraints
         | 
| 76 76 | 
             
                      elsif column.searchable? && params[column.name] != v
         | 
| @@ -79,7 +79,7 @@ module ActiveScaffold | |
| 79 79 | 
             
                      end
         | 
| 80 80 | 
             
                    # unknown-to-activescaffold-but-real-database-column constraint
         | 
| 81 81 | 
             
                    elsif active_scaffold_config.model.columns_hash[k.to_s] && params[column.name] != v
         | 
| 82 | 
            -
                      hash_conditions. | 
| 82 | 
            +
                      hash_conditions.deep_merge!(k => v)
         | 
| 83 83 | 
             
                    else
         | 
| 84 84 | 
             
                      raise ActiveScaffold::MalformedConstraint, constraint_error(active_scaffold_config.model, k), caller
         | 
| 85 85 | 
             
                    end
         | 
| @@ -96,33 +96,32 @@ module ActiveScaffold | |
| 96 96 | 
             
                  #
         | 
| 97 97 | 
             
                  # please see the relevant tests for concrete examples.
         | 
| 98 98 |  | 
| 99 | 
            -
                  field =
         | 
| 100 | 
            -
             | 
| 101 | 
            -
             | 
| 102 | 
            -
             | 
| 103 | 
            -
                      association.options[:foreign_key] || association.name.to_s.foreign_key
         | 
| 99 | 
            +
                  field = if association.belongs_to?
         | 
| 100 | 
            +
                            association.foreign_key
         | 
| 101 | 
            +
                          else
         | 
| 102 | 
            +
                            association.klass.primary_key
         | 
| 104 103 | 
             
                    end
         | 
| 105 104 |  | 
| 106 | 
            -
                  table =  | 
| 107 | 
            -
                    when :belongs_to then active_scaffold_config.model.table_name
         | 
| 108 | 
            -
                    else association.table_name
         | 
| 109 | 
            -
                  end
         | 
| 105 | 
            +
                  table = association.belongs_to? ? active_scaffold_config.model.table_name : association.table_name
         | 
| 110 106 |  | 
| 111 | 
            -
                  if association. | 
| 112 | 
            -
                    value = association.klass.find(value).send(association. | 
| 107 | 
            +
                  if association.primary_key
         | 
| 108 | 
            +
                    value = association.klass.find(value).send(association.primary_key)
         | 
| 113 109 | 
             
                  end
         | 
| 114 110 |  | 
| 115 | 
            -
                   | 
| 116 | 
            -
             | 
| 117 | 
            -
             | 
| 118 | 
            -
                     | 
| 111 | 
            +
                  if association.polymorphic?
         | 
| 112 | 
            +
                    unless value.is_a?(Array) && value.size == 2
         | 
| 113 | 
            +
                      raise ActiveScaffold::MalformedConstraint, polymorphic_constraint_error(association), caller
         | 
| 114 | 
            +
                    end
         | 
| 115 | 
            +
                    condition = {table => {association.foreign_type => value[0], field => value[1]}}
         | 
| 116 | 
            +
                  else
         | 
| 117 | 
            +
                    condition = {table => {field.to_s => value}}
         | 
| 119 118 | 
             
                  end
         | 
| 120 119 |  | 
| 121 120 | 
             
                  condition
         | 
| 122 121 | 
             
                end
         | 
| 123 122 |  | 
| 124 123 | 
             
                def polymorphic_constraint_error(association)
         | 
| 125 | 
            -
                  "Malformed constraint. You have added a constraint for #{association.name} polymorphic association but  | 
| 124 | 
            +
                  "Malformed constraint. You have added a constraint for #{association.name} polymorphic association but value is not an array of class name and id."
         | 
| 126 125 | 
             
                end
         | 
| 127 126 |  | 
| 128 127 | 
             
                def constraint_error(klass, column_name)
         | 
| @@ -139,15 +138,19 @@ module ActiveScaffold | |
| 139 138 | 
             
                # If it *is* ok (e.g. you're in a transaction), then set :allow_autosave to true.
         | 
| 140 139 | 
             
                def apply_constraints_to_record(record, options = {})
         | 
| 141 140 | 
             
                  options[:allow_autosave] = false if options[:allow_autosave].nil?
         | 
| 141 | 
            +
                  constraints = options[:constraints] || active_scaffold_constraints
         | 
| 142 142 |  | 
| 143 | 
            -
                   | 
| 144 | 
            -
             | 
| 143 | 
            +
                  config = record.is_a?(active_scaffold_config.model) ? active_scaffold_config : active_scaffold_config_for(record.class)
         | 
| 144 | 
            +
                  constraints.each do |k, v|
         | 
| 145 | 
            +
                    column = config.columns[k]
         | 
| 145 146 | 
             
                    if column && column.association
         | 
| 146 | 
            -
                      if column. | 
| 147 | 
            -
                        record.send( | 
| 148 | 
            -
                      elsif column.association. | 
| 149 | 
            -
                         | 
| 150 | 
            -
             | 
| 147 | 
            +
                      if column.association.collection?
         | 
| 148 | 
            +
                        record.send(k.to_s).send(:<<, column.association.klass.find(v))
         | 
| 149 | 
            +
                      elsif column.association.polymorphic?
         | 
| 150 | 
            +
                        unless v.is_a?(Array) && v.size == 2
         | 
| 151 | 
            +
                          raise ActiveScaffold::MalformedConstraint, polymorphic_constraint_error(column.association), caller
         | 
| 152 | 
            +
                        end
         | 
| 153 | 
            +
                        record.send("#{k}=", v[0].constantize.find(v[1]))
         | 
| 151 154 | 
             
                      else # regular singular association
         | 
| 152 155 | 
             
                        record.send("#{k}=", column.association.klass.find(v))
         | 
| 153 156 |  | 
| @@ -156,9 +159,9 @@ module ActiveScaffold | |
| 156 159 | 
             
                        #
         | 
| 157 160 | 
             
                        # note that we can't take the extra step to correct this unless we're permitted to
         | 
| 158 161 | 
             
                        # run operations where activerecord auto-saves the object.
         | 
| 159 | 
            -
                        reverse = column.association. | 
| 160 | 
            -
                        if reverse. | 
| 161 | 
            -
                          record.send(k).send("#{ | 
| 162 | 
            +
                        reverse = column.association.reverse_association
         | 
| 163 | 
            +
                        if reverse.singular? && !reverse.belongs_to? && options[:allow_autosave]
         | 
| 164 | 
            +
                          record.send(k).send("#{reverse.name}=", record)
         | 
| 162 165 | 
             
                        end
         | 
| 163 166 | 
             
                      end
         | 
| 164 167 | 
             
                    else
         |