为排名模型 gem 排序 UI

sorting UI for ranked-model gem

我正在尝试使排序 UI 与 gem ranked-model 一起工作。

宝石文件:

gem 'ranked-model'
gem 'jquery-ui-rails' #for drag-and-drop

application.js:

//= require jquery-ui/widgets/sortable

lesson.rb:

class Lesson < ApplicationRecord include RankedModel ranks :row_order end

lessons_controller.rb - 添加排序功能:

class LessonsController < ApplicationController
  def index
    @lessons = Lesson.rank(:row_order)
  end

  def sort
    lesson = Lesson.find(params[:lesson_id])
    lesson.update(lesson_params)
    render body: nil
  end

  private
    def lesson_params
      params.require(:lesson).permit(:name, :row_order_position)
    end
end

路线:

Rails.application.routes.draw do
  resources :lessons do
    put :sort
  end
end

这样路线看起来像这样:

lessons.html.haml:

%h1 Lessons
%table.table
  %thead
    %tr
      %th Name
  %tbody#item{"data-model_name": "lesson.class.name.underscore", "data-update_url": "lesson_sort_path(lesson)"}
    - @lessons.each do |lesson|
      %tr
        %td= lesson.name

table_sort.js:

$(function(){
  $('#item').sortable({
    update: function(e, ui){
      var item = ui.item;
      var item_data = item.data();
      var params = {_method: 'put'};
      params[item_data.modelName] = { row_order_position: item.index() }
      $.ajax({
        type: 'POST',
        url: item_data.updateUrl,
        dataType: 'json',
        data: params
      });
    }
  });
});

排序有效,但它没有持久化,我在日志中收到以下错误。知道如何保持排序吗?

  %tbody#item{"data-model_name": "lesson.class.name.underscore", "data-update_url": "lesson_sort_path(lesson)"}
- @lessons.each do |lesson|

你应该颠倒这两行,因为 lessor_sort_path(lesson) 需要 lesson 变量。这就是为什么你在更新时得到错误的 PUT /lessons/ 路径。也许是这样的(我不熟悉 Haml):

  %tbody#item
- @lessons.each do |lesson|
  %tr{"data-model_name": "lesson.class.name.underscore", "data-update_url": "lesson_sort_path(lesson)"}

这是我想出的有效解决方案。

观点:

.list-group.lesson-sortable
  - @lessons.each do |lesson|
    = content_tag "div", id: "lesson-#{lesson.id}", data: { model_name: lesson.class.name.underscore, update_url: lesson_sort_path(lesson)} do
      = lesson.name

JS:

$(function(){
  $('.lesson-sortable').sortable({
    update: function(e, ui){
      let item = ui.item;
      let item_data = item.data();
      let params = {_method: 'put'};
      params[item_data.modelName] = { row_order_position: item.index() }
      $.ajax({
        type: 'POST',
        url: item_data.updateUrl,
        dataType: 'json',
        data: params
      });
    },
    stop: function(e, ui){
      console.log("stop called when finishing sort of cards");
    }
  });
});