Rails 3.2 jQuery sortable list 500 error with nested resources

拥有回忆 提交于 2019-12-25 02:24:18

问题


Following the Railscasts episode about sortable lists (http://railscasts.com/episodes/147-sortable-lists-revised?view=asciicast), I've got everything in place, however instead of doing sorting on the model whose #show action is displaying the list, it's a nested model.

My site is for managing a very complex fantasy football league. One of the aspects of the league is that GMs have a yearly salary cap amount, players have a value, and players can be signed to multi-year contracts.

Anyway, I'm creating a draft roster list that lets you add players and keep track of the ones you want to try and draft. I want this list to be sortable. I have it setup using a has_many :through relationship.

Here are the three models:

class DraftRoster < ActiveRecord::Base
  attr_accessible :name, :team_id

  belongs_to :team

  has_many :roster_spots
  has_many :players, through: :roster_spots
  ...
end

Then:

class RosterSpot < ActiveRecord::Base
  attr_accessible :draft_roster_id, :player_id, :position
  belongs_to :draft_roster
  belongs_to :player

  acts_as_list
end

And finally (this has a LOT more code removed here as its not applicable to this issue):

class Player < ActiveRecord::Base
  attr_accessible :auction_value, :first_name, :last_name, :nfl_team, :position, :is_drafted, :is_bought_out, :is_extended, :is_franchised, :bye_week, :full_name, :contracts_attributes, :subcontracts_attributes
  ...
  has_many :roster_spots
  has_many :draft_rosters, through: :roster_spots
  ...
end

So I've gone through and I've follow the Railscasts episode exactly. My #sort action is in the roster_spots_controller.rb file (and the position attribute is also on this model).

draft_rosters_controller.rb

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

And I have the necessary route:

resources :roster_spots do
  collection { post :sort }
end

The Coffeescript:

jQuery ->
  $('#draft-roster-players').sortable(
    axis: 'y'
    handle: '.handle'
    update: ->
      $.post($(this).data('update-url'), $(this).sortable('serialize'))
)

The draft_rosters#show action:

def show
  @draft_roster = DraftRoster.find(params[:id])
  @team = @draft_roster.team
  @players = @draft_roster.players.order("position")

  respond_to do |format|
    format.html # show.html.erb
    format.json { render json: @draft_roster }
  end
end

And finally, the view:

<ul id="draft-roster-players" data-update-url="<%= sort_roster_spots_url %>">
  <% @players.each do |player| %>
    <%= content_tag_for :li, player do %>
        <span class="handle">[drag]</span>
        <%= link_to h(player.full_name), player %>
    <% end %>
  <% end %>
</ul>

Everything is dragging and dropping as expected, but when I drop a player into a new spot on the list, in the Chrome JavaScript console, I keep getting this error:

 POST http://localhost:3000/roster_spots/sort 500 (Internal Server Error)
   send
   x.extend.ajax
   x.(anonymous function)
   $.sortable.update
   $.Widget._trigger
   $.widget._trigger
   (anonymous function)
   (anonymous function)
   $.widget._clear
   (anonymous function)
   $.widget._mouseStop
   (anonymous function)
   $.widget._mouseUp
   (anonymous function)
   _mouseUpDelegate
   x.event.dispatch
   v.handle

I don't get it. The only thing I can think of is that it somehow has to do with the nested resources, but I don't see why that would matter necessarily. A few comments on the Railscasts episode alluded to having some issues with nested resources, but none of them provided the solution they used to get it working and they're from years ago.

Has anyone done sortable lists through jQuery in a Rails 3.2 app? What's the trick necessary to get it working? I've tried passing a few variables to the data-update-url attribute on the tag but nothing has worked.

Any help would be appreciated!

UPDATE Stupidly, I never checked the Rails console output...I'm getting this error:

NoMethodError (undefined method `each_with_index' for nil:NilClass):
  app/controllers/roster_spots_controller.rb:89:in `sort'

回答1:


Figured it out looking at the console output! I had to make the following changes:

draft_rosters#show view:

<ul id="draft-roster-players" data-update-url="<%= sort_roster_spots_url %>">
<% @roster_spots.each do |roster_spot| %>
    <%= content_tag_for :li, roster_spot do %>
        <span class="handle">[drag]</span>
        <%= link_to h(roster_spot.player.full_name), roster_spot %>
    <% end %>
<% end %>
</ul>

draft_rosters#show action:

def show
  @draft_roster = DraftRoster.find(params[:id])
  @team = @draft_roster.team
  @roster_spots = @draft_roster.roster_spots.order("position")

  respond_to do |format|
    format.html # show.html.erb
    format.json { render json: @draft_roster }
  end
end

roster_spots_controller.rb

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

And now it's working as it should be. :) I hope that this can be of help to others should they find themselves in this situation.



来源:https://stackoverflow.com/questions/22884753/rails-3-2-jquery-sortable-list-500-error-with-nested-resources

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!