在 Railscasts 关于可排序列表的剧集 (http://railscasts.com/episodes/147-sortable-lists-revised?view=asciicast) 之后,我已经准备好了一切,但是不是对 #show 操作显示列表的模型进行排序,它是一个嵌套模型。
我的网站用于管理一个非常复杂的梦幻足球联赛。联盟的一个方面是,总经理有年薪帽金额,球员有价值,球员可以签下多年合同。
无论如何,我正在创建一个草稿名单列表,可让您添加球员并跟踪您想要尝试和选秀的球员。我希望此列表可排序。我使用has_many:通过关系设置它。
以下是三种模型:
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
咖啡脚本:
jQuery ->
$('#draft-roster-players').sortable(
axis: 'y'
handle: '.handle'
update: ->
$.post($(this).data('update-url'), $(this).sortable('serialize'))
)
draft_rosters#show 操作:
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 属性,但没有任何效果。
任何帮助将不胜感激!
更新愚蠢地,我从未检查过 Rails 控制台输出......我收到此错误:
NoMethodError (undefined method `each_with_index' for nil:NilClass):
app/controllers/roster_spots_controller.rb:89:in `sort'
查看控制台输出就想通了!我必须进行以下更改:
draft_rosters#显示视图:
<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#显示动作:
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
现在它正在按应有的方式工作。:)我希望,如果他们发现自己处于这种情况,这可以对其他人有所帮助。