0

I'm implementing drag and drop functionality to my Rails 4 application. I've been following along the tutorial video by Ryan Bates, #147 Sortable Lists (revised)

I can drag the rows along, but the changes don't get persisted in the database.

On my view (app/views/admin/sections/index.html.erb), I implemented the drag and drop functionality like this:

<section class="dashboard">
  <%= button_to "Sectie Toevoegen", new_admin_section_path, method: "get" %>
  <table id="sections" class="table-borders">
    <tbody data-update-url="<%= sort_admin_sections_url %>">
    <% @sections.each do |section| %>
      <%= content_tag_for :tr, section do %>
        <td><%= link_to section.title, admin_section_path(section) %></td>
        <td><%= link_to "Aanpassen", edit_admin_section_path(section) %>&nbsp;&nbsp;<%= link_to 'Verwijderen', admin_section_path(section), method: :delete, data: { confirm: "Ben je zeker?" } %>   </td>
        <% end %>
    <% end %>
    </tbody>
  </table>

I'm not sure if the sort action (which has the update logic) gets triggered or not. The code for my sort action looks like this:

app/controllers/admin/sections_controller.rb

def sort
  params[:section].each_with_index do |id, index|
    Section.where(id: id).update_all({position: index+1})
  end
  render nothing: true
end

my routes are defined like this:

  namespace :admin do
  ...
    resources :sections do
      collection { post :sort }
    end
  end

The update callback in the jquery ui sortable method gets called(app/assets/javascripts/sections.js.coffee):

jQuery ->
  $('#sections tbody').sortable
    axis: 'y'
    update: ->
      $.post($(this).data('update_url'), $(this).sortable('serialize'))

, I checked this with a simple alert() method. Also when I check the Javascript through the Google Developer Tools console, I see no Javascript errors.

I think the problem must be caused by the mass assignment security by Rails. When I tail the development log, while dragging a row, I see this error message:

Started POST "/admin/sections" for 127.0.0.1 at 2014-11-13 20:45:04 +0100
Processing by Admin::SectionsController#create as */*
  Parameters: {"section"=>["3", "4", "6", "2", "5"]}
Completed 500 Internal Server Error in 1ms

NoMethodError (undefined method `permit' for ["3", "4", "6", "2", "5"]:Array):
app/controllers/admin/sections_controller.rb:54:in `section_params'
app/controllers/admin/sections_controller.rb:15:in `create'

I tried to solve this by adding ':position => []' to my list of allowed parameters:

  def section_params
    params.require(:section).permit(:title, :description, :image, :category_id)
  end

but that doesn't fix the issue.

My repository is at: https://github.com/acandael/beautysalonapp2/tree/drag-and-drop

thanks for your help,

Anthony

Toontje
  • 1,415
  • 4
  • 25
  • 43
  • You need to show some relevant code where you think something is happening as expected. – Surya Nov 13 '14 at 19:07
  • ok, I added some code, thanks for pointing this out – Toontje Nov 13 '14 at 19:25
  • Did you even see the error? You're calling `POST "/admin/sections"` but it goes to `Admin::SectionsController#create` instead of `Admin::SectionsController#sort`. That's why it's not working. Can you post your routes as well? – Surya Nov 13 '14 at 20:09
  • I added my route. The resource :sections is namespaced by Admin. When I look at the page source, the link seems properly rendered: – Toontje Nov 13 '14 at 20:15
  • The problem is at this line: `$.post($(this).data('update_url'), $(this).sortable('serialize'))` then, check if `$(this).data('update_url')` is `localhost:3000/admin/sections/sort` or not. – Surya Nov 13 '14 at 20:27

0 Answers0