Rails 3.2 jQuery可排序列表500错误与嵌套资源

时间:2014-04-05 18:11:03

标签: jquery ruby-on-rails ruby-on-rails-3 jquery-ui

在关于可排序列表(http://railscasts.com/episodes/147-sortable-lists-revised?view=asciicast)的Railscasts剧集之后,我已经掌握了所有内容,但是不是在#show操作显示列表的模型上进行排序,而是' sa嵌套模型。

我的网站是为了管理一个非常复杂的梦幻足球联赛。联盟的一个方面是,总经理有年薪上限,球员有价值,球员可以签订多年合同。

无论如何,我正在创建一个草稿名单列表,可让您添加玩家并跟踪您想要尝试和选择的玩家。我希望这个列表是可排序的。我使用has_many:through relationship设置它。

以下是三种模式:

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

  belongs_to :team

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

然后:

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

  acts_as_list
end

最后(这里有很多代码被移除,因为它不适用于这个问题):

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

所以我已经完成了,并且我完全按照Railscasts的情节进行了操作。我的#sort操作位于roster_spots_controller.rb文件中(位置属性也在此模型上)。

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

我有必要的路线:

resources :roster_spots do
  collection { post :sort }
end

Coffeescript:

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

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

最后,观点:

<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>

所有内容都按预期拖放,但当我将播放器放入列表中的新位置时,在Chrome JavaScript控制台中,我不断收到此错误:

 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

我不明白。我唯一能想到的是,它与嵌套资源有某种关系,但我不明白为什么这一点必然存在。关于Railscasts剧集的一些评论暗示了嵌套资源存在一些问题,但是他们都没有提供他们用来使其工作的解决方案,而且他们是多年前的。

有人在Rails 3.2应用程序中通过jQuery完成了可排序列表吗?让它运作所需的诀窍是什么?我已经尝试将一些变量传递给标记上的data-update-url属性,但没有任何效果。

任何帮助将不胜感激!

UPDATE 愚蠢的是,我从未检查过Rails控制台输出...我收到此错误:

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

1 个答案:

答案 0 :(得分:0)

看着控制台输出!我不得不做出以下改变:

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

现在它应该正常工作。 :)我希望如果他们发现自己处于这种状况,这对他人有帮助。