Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature Request: Selectively do not update the position field in "sort" action #96

Open
awh-tokyo opened this issue Apr 11, 2022 · 2 comments

Comments

@awh-tokyo
Copy link

awh-tokyo commented Apr 11, 2022

My use case is that I would like a tree structure, but to have each level always sorted by name. I'd like to have the tree editor still work for easily setting parent/child relationships.

Currently I have to override the "sort" controller action so that it does not update the "position" field (which I have set to 'name'), or else all my objects get their name changed to numbers:

  # Override the one provided by ActiveAdminSortable, since we want it to ignore updates to the sort order
  collection_action :sort, :method => :post do
    resource_name = ActiveAdmin::SortableTree::Compatibility.normalized_resource_name(active_admin_config.resource_name)

    records = []
    params[resource_name].each_pair do |resource, parent_resource|
      parent_resource = resource_class.find(parent_resource) rescue nil
      records << [resource_class.find(resource), parent_resource]
    end

    errors = []
    ActiveRecord::Base.transaction do
      records.each_with_index do |(record, parent_record), position|
        # record.send "#{options[:sorting_attribute]}=", position
        if options[:tree]
          record.send "parent=", parent_record
        end
        errors << {record.id => record.errors} if !record.save
      end
    end
    if errors.empty?
      head 200
    else
      render json: errors, status: 422
    end
  end

Could we have a config option that allows us to disable the record.send "#{options[:sorting_attribute]}=", position ?

@zorab47
Copy link
Owner

zorab47 commented Jul 14, 2022

Thanks for posting the feature request!

How would the sorting be persisted? Could your model have a virtual no-op setter for :sorting_attribute?

class NamedTreeNode
  def no_op_sorting_attribute=(*)
    # do nothing
  end

  def parent=(record)
    # handle setting parent record
  end
end

Note: This assumes I fully recall how this library works.

@awh-tokyo
Copy link
Author

awh-tokyo commented Oct 4, 2023

I'm revisiting this because I thought about it while trying to clean up some code. The problem with your suggestion is that the :sorting_attribute is used as the sort order in index_as_sortable.rb:

          ol do
            item.send(options[:children_method]).order(options[:sorting_attribute]).each do |c|
              build_nested_item(c)
            end
          end if tree?

Setting the sorting_attribute to no_op_sorting_attribute causes the SQL generated by ActiveRecord to sort by a nonexistent column.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants