ドラックアンドドロップ機能実装
解決したいこと
ドラックアンドドロップ機能において画面更新時に順番が保存されない
Ruby on Railsでお気に入りの店舗を登録することのできるWebアプリをつくっています。
ドラックアンドロップで要素を動かすことはできるのですが、画面を更新すると順番が保存されていませんでした。ドラックアンドドロップ機能はshopのindexに表示させています。以下の記事を参考に作成しました。
https://qiita.com/fumikao/items/77ffdffc24a9a814fad7
解決方法を教えて下さい。
以下は、検証ツールで発生しているエラーです
発生している問題・エラー
Failed to load resource: the server responded with a status of 422 ()
該当するソースコード
table.sort.js
$(function(){
$('.table-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){
ui.item.children('td').not('.item__status').effect('highlight', { color: "#FFFFCC" }, 500)
}
});
});
shops_controller
def index
@shops = Shop.page(params[:page]).rank(:row_order)
end
routes.rb
def index
@shops = Shop.page(params[:page]).rank(:row_order)
end
private
def shop_params
params.require(:shop).permit(:shop_name, :image, :address, :comment, :user_id, :row_order_position)
end
application.js
//= require jquery
//= require rails-ujs
//= require activestorage
//= require turbolinks
//= require_tree .
//= require jquery-ui/widgets/sortable
//= require jquery-ui/effects/effect-highlight
//= require moment
//= require fullcalendar
//= require bootstrap-sprockets
index.html.erb
<table class="table">
<thead class="thead-dark">
<tr>
<th>店舗画像</th>
<th>店舗名</th>
<th>住所</th>
</tr>
</thead>
<tbody class="bg-light table-sortable">
<% @shops.each do |shop| %>
<tr>
<%= content_tag "tr", class: "item", data: { model_name: shop.class.name.underscore, update_url: shop_sort_path(shop)} do %>
<td>
<%= link_to shop_path(shop.id) do %>
<%= attachment_image_tag shop, :image, size: '200x150', formate: 'jpg', fallback: "no_iamge.jpg" %>
<% end %>
</td>
<td class="pt-4">
<%= link_to shop_path(shop.id) do %>
<%= shop.shop_name %>
<% end %>
</td>
<td class="pt-4"><%= shop.address %></td>
</tr>
<% end %>
<% end %>
<%= paginate @shops %>
</tbody>
</table>
schema.rb
create_table "shops", force: :cascade do |t|
t.string "shop_name", null: false
t.string "image_id", null: false
t.string "address", null: false
t.text "comment", null: false
t.datetime "created_at", null: false
t.integer "user_id"
t.datetime "updated_at"
t.string "conversion_shop_name"
t.string "conversion_address"
t.integer "row_order"
end
shop.rb
class Shop < ApplicationRecord
include RankedModel #ドラックアンドドロップ
ranks :row_order, with_same: :user_id
belongs_to :user
has_many :products, dependent: :destroy
has_many :genres, dependent: :destroy
has_many :favorites, dependent: :destroy
has_many :bookmarks, dependent: :destroy
has_many :shop_comments, dependent: :destroy
has_many :notifications, dependent: :destroy
attachment :image
validates :shop_name, presence: true
validates :address, presence: true
validates :comment, presence: true
def bookmarked_by?(user)
bookmarks.where(user_id: user).exists?
end
def favorited_by?(user)
favorites.where(user_id: user.id).exists?
end
def self.search_for(content, method)
Shop.where('conversion_shop_name LIKE ?', '%'+content+'%')
end
def self.searched_for(content, method)
Shop.where('address LIKE ?', '%'+content+'%')
end
def self.sort(selection) #いいね順並び替え
case selection
when 'new'
return all.order(created_at: :DESC)
when 'old'
return all.order(created_at: :ASC)
when 'likes'
return find(Favorite.group(:shop_id).order(Arel.sql('count(shop_id) desc')).pluck(:shop_id))
when 'dislikes'
return find(Favorite.group(:shop_id).order(Arel.sql('count(shop_id) asc')).pluck(:shop_id))
end
end
def create_notification_favorite!(current_user)#通知機能の記述
# すでに「いいね」されているか検索
temp = Notification.where(["visitor_id = ? and visited_id = ? and shop_id = ? and action = ? ", current_user.id, user_id, id, 'favorite'])
# いいねされていない場合のみ、通知レコードを作成
if temp.blank?
notification = current_user.active_notifications.new(
shop_id: id,
visited_id: user_id,
action: 'favorite'
)
# 自分の投稿に対するいいねの場合は、通知済みとする
if notification.visitor_id == notification.visited_id
notification.checked = true
end
notification.save if notification.valid?
end
end
def create_notification_comment!(current_user, shop_comment_id)
# 自分以外にコメントしている人をすべて取得し、全員に通知を送る
temp_ids = ShopComment.select(:user_id).where(shop_id: id).where.not(user_id: current_user.id).distinct
temp_ids.each do |temp_id|
save_notification_comment!(current_user, shop_comment_id, temp_id['user_id'])
end
# まだ誰もコメントしていない場合は、投稿者に通知を送る
save_notification_comment!(current_user, shop_comment_id, user_id) if temp_ids.blank?
end
def save_notification_comment!(current_user, shop_comment_id, visited_id)
# コメントは複数回することが考えられるため、1つの投稿に複数回通知する
notification = current_user.active_notifications.new(
shop_id: id,
shop_comment_id: shop_comment_id,
visited_id: visited_id,
action: 'shop_comment'
)
# 自分の投稿に対するコメントの場合は、通知済みとする
if notification.visitor_id == notification.visited_id
notification.checked = true
end
notification.save if notification.valid?
end
end
自分で試したこと
ターボリンクスを無効化することでうまくいくというような記事を見つけたので現在実行しているのですが、ターボリンクスを無効化するとドラックアンドドロップが動かなくなったりするのでうまくいきません。
https://qiita.com/d0ne1s/items/5a4122d2972be3812986