All threads / Sortable Drag and Drop
Ask A Question


You’re not receiving notifications from this thread.

Sortable Drag and Drop

Clay asked in Rails


I am hoping someone can assist. I have gone through the tutorial of Srttable Drag and Drop.

All is working but once the drop happens I am getting a NoMethodError
NoMethodError (undefined methodeach_with_index' for nil:NilClass):`

This is happening on the sort action in the controller (mine being admin/products)

def sort
    params[:product].each_with_index do |id, index|
        Product.where(id: id).update_all(position: index + 1)

    head :ok

Anyone know what could be causing this ?

Hi Clay,

If you throw a byebug in your action before you start iterating, you'll get a console where you can test what the params are and see if the id's are even present in the params hash or that your key is actually :product.

Can you post your view where you have your sortable list and the js?

Hi Jacob

Thanks for a idea. Here is the byebug result.
[1070, 1079] in /Users/Clayton/.rvm/gems/ruby-2.5.1/gems/actionpack-5.2.0/lib/action_controller/metal/strong_parameters.rb
1070: include ActiveSupport::Rescuable
1072: # Returns a new ActionController::Parameters object that
1073: # has been instantiated with the request.parameters.
1074: def params
=> 1075: @_params ||=
1076: end
1078: # Assigns the given +value+ to the +params+ hash. If +value+
1079: # is a Hash, this will create an ActionController::Parameters

admin/products controller

def sort
    params[:product].each_with_index do |id, index|
        Product.where(id: id).update_all(position: index + 1)
    head :ok


document.addEventListener("turbolinks:load", function() {

        update: function(e, ui) {
                url: $(this).data("url"),
                type: "PATCH",
                data: $(this).sortable('serialize'),

Admin Products Index

<tbody id="products" data-url="<%= sort_admin_products_path %>">
   <%= render @products %>

Admin Products - Product

  <td><%= link_to product.product_code, admin_product_path(product), id: dom_id(product) %> - (<%= product.position %>)</td>
  <td><%= product.product_name.truncate(45) %></td>
  <td><%= link_to 'Edit', edit_admin_product_path(product), class: 'btn btn-sm btn-warning' %></td>
  <td><%=button_to "Remove", admin_product_path(product), method: :delete, data: { confirm: 'Are you sure?' }, :class => 'btn btn-sm btn-danger' %></td>

Ahh, I think your problem is how you're identifying your sortable objects. I haven't tested this or even done the sorting on a table so this could be wrong, but you're putting the id: dom_id(product) on a <td> tag and I believe it should be on the <tr> tag.

As for the byebug result, you should do something like this:

def sort
    params[:product].each_with_index do |id, index|
        Product.where(id: id).update_all(position: index + 1)

    head :ok

And then refresh the page. Now look at your terminal where you started your rails server at and you should now have a command prompt where you can type in params then hit enter and get the params for that request.

Sorry, small correction to the byebug instructions...

You'll refresh your page and then try rearranging your rows. The first time you move a row into a new slot it should fire the ajax request which should now trigger the byebug instance in your console. Now you can type in params and see the params that were sent over in the request to see if you're getting anything at all related to your rearranged rows.

Hi thanks for the suggestions.
Here is the result of the params
"admin/products", "action"=>"sort"} permitted: false>

The Dom it is on the link_to tag within the td. Not sure if it should be moved out but here it is displaying correctly.

Displaying ok != working ok

Result of params shows that the ID's aren't being grabbed by the JS. So since all your code on the JS looks good, then the process of elimination is saying it's because you're defining your id on the <td> instead of <tr>

Did you move id: dom_id(product) to the <tr> tag?

Please do that and then test. I just modified one of my implementations and it does not work if I put the ID on the <td> tag but it works as expected when I move it to the <tr> tag.


Ok added as per your suggestion
Thanks once again have a great one!
Join the discussion

Want to stay up-to-date with Ruby on Rails?

Join 68,326+ developers who get early access to new tutorials, screencasts, articles, and more.

    We care about the protection of your data. Read our Privacy Policy.

    logo Created with Sketch.

    Screencast tutorials to help you learn Ruby on Rails, Javascript, Hotwire, Turbo, Stimulus.js, PostgreSQL, MySQL, Ubuntu, and more. Icons by Icons8

    © 2022 GoRails, LLC. All rights reserved.