
・ Ruby: 2.5.7 Rails: 5.2.4 ・ Vagrant: 2.2.7 -VirtualBox: 6.1 ・ OS: macOS Catalina
The following has been implemented.
・ Slim introduction ・ Introduction of Bootstrap3 ・ Implementation of posting function
Gemfile
#Postscript
gem 'jquery-ui-rails'
gem 'ranked-model'
jquery-ui-rails
➡︎ Make jQuery UI available.
gem 'ranked-model'
➡︎ Make it possible to manage the order of books.
Terminal
$ rails g migration AddRowOrderToBooks row_order:integer
Terminal
$ bundle
schema.rb
create_table "books", force: :cascade do |t|
  t.integer "user_id"
  t.string "title"
  t.text "body"
  t.datetime "created_at", null: false
  t.datetime "updated_at", null: false
  t.integer "row_order"
end
Allow ranked-model to be used in Book models.
book.rb
#Postscript
include RankedModel
ranks :row_order
** ① Edit ʻindex action` **
books_controller.rb
#Change before
@books = Book.all
#After change
@books = Book.rank(:row_order)
** ② Add row_order_position to the strong parameter. ** **
The column name is row_order, but here it is described as row_order_position for the purpose of using Gem.
books_controller.rb
def book_params
  params.require(:book).permit(:title, :body, :row_order_position)
end
** ③ Add sort action **
books_controller.rb
def sort
  book = Book.find(params[:book_id])
  book.update(book_params)
  render body: nil
end
render body: nil
➡︎ Perform only actions, do not call views.
route.rb
#Change before
resources :books
#After change
resources :books do
  put :sort
end
slim:books/index.html.slim
/ 「table-Grant a class called "sortable"
table.table.table-bordered.table-sortable
  thead
    tr
      th
        |Contributor
      th
        |title
      th
        |Text
      th
  tbody
    - @books.each do |book|
      /Assign a class to the tr tag and set the data
      tr.item(data = { model_name: book.class.name.underscore, update_url: book_sort_path(book) })
        td
          = link_to book.user  do
            = book.user.name
        td
          = link_to book.title, book_path(book)
        td
          = book.body
        td
          -if book.user == current_user
            = link_to 'Delete', book, method: :delete, data: { confirm: '本当にDeleteしてもよろしいですか?' }, class: 'btn-sm btn-danger'
model_name: book.class.name.underscore
➡︎ "book" corresponds to each block variable.
application.js
//= require rails-ujs
//= require activestorage
//= require turbolinks
//= require jquery
//= require jquery-ui/widgets/sortable //Postscript
//= require jquery-ui/effects/effect-highlight //Postscript
//= require bootstrap-sprockets
//= require_tree .
//= require jquery-ui/widgets/sortable
➡︎ Enable jQuery UI
//= require jquery-ui/effects/effect-highlight
➡︎ Enable drag and drop effects
Terminal
$ touch app/assets/javascripts/table_sort.js
table_sort.js
$('.table-sortable').sortable({
  axis: 'y',
  items: '.item',
  //Send order data to controller with Ajax
  update(e, ui) {
    let item = ui.item;
    let item_data = item.data();
    let params = { _method: 'put' };
    params[item_data.model_name] = { row_order_position: item.index() };
    $.ajax({
      type: 'POST',
      url: item_data.update_url,
      dataType: 'json',
      data: params,
    });
  },
  //Adjust drag width to table
  start(e, ui) {
    let cells, tableWidth, widthForEachCell;
    tableWidth = $(this).width();
    cells = ui.item.children('td');
    widthForEachCell = tableWidth / cells.length + 'px';
    return cells.css('width', widthForEachCell);
  },
  //Add effect
  stop(e, ui) {
    return ui.item.children('td').effect('highlight');
  },
});
application.scss
//Postscript
.table-sortable {
  tr.item {
    cursor: row-resize;
  }
}
        Recommended Posts