この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。
accepts_nested_attributes_for用のフォームをサポートしてくれる「nested_form」にドラッグ&ドロップで並び順を変更できる「jquery-ui/sortable」を導入する方法を記述します。
事前準備
1.Gemfileに追記
$ vim Gemfile
gem 'jquery-rails'
gem 'jquery-ui-rails'
gem 'nested_form'
2.モデルにaccepts_nested_attributes_forを追記
例としてBlog-< Entryな関連でEntryが並び順に使用するカラム(position)を所持
$ vim app/models/blog.rb
has_many :entries
accepts_nested_attributes_for :entries, allow_destroy: true
$ vim app/models/entry.rb
belongs_to :blog
3.コントローラにpositionパラメータを取得できるように追記
$ vim app/controllers/blogs_controller.rb
def blog_params
params.require(:blog).permit(
....,
entries_attributes: [
...,
:position
]
)
end
viewでの記述
$ vim app/views/blogs/_form.slim
= nested_form_for(@blog, url: ...) do |f|
....
table#entries.table.table-striped.table-sortable
= f.fields_for :entries, wrapper: false
br
.pull-right.
= f.link_to_add '追加', :entries, data: { target: '#entries' }, class: 'btn btn-default'
$ vim app/views/blogs/_entry_fields.slim
tr.fields.form-group
td ...
...
td
.pull-right
= f.link_to_remove '削除', class: 'btn btn-danger'
= f.hidden_field :position, class: :position
js.coffeeでの記述
$ vim app/assets/javascripts/blog.js.coffee
$ ->
...
# 並び替え
$('.table-sortable').sortable
axis: 'y',
items: '.fields',
update: (e, ui) ->
# ドラッグ&ドロップしたら各entryのhidden_fieldに現在の位置を入れる
$('.position').each ->
$(this).val($('.position').index($(this)) + 1)
以上でフォームをsubmitした時にドラッグ&ドロップで変更したpositionパラメータが取得できる様になります。