■スライダー機能とは?
下記のように、画面をスライドさせることで画面遷移を実現できるようにしたもの。
https://i.gyazo.com/930bdc23e9290131b0d6a591a79d43f5.mp4
■Swiperとは?
Rails上でスライダー機能を実装することを可能にするツールのこと。
==========================================================================
■導入手順
npmでSwiperをインストール
$ npm install swiper
└node_modulesディレクトリ配下に必要なファイルが作成される。
読み込み設定
導入したnode_modules配下のファイルを読み込むようにするための設定をconfig/initializers/assets.rbに追記します。
config/initializers/assets.rb
Rails.application.config.assets.paths << Rails.root.join('node_modules')
application.css.scssとapplication.jsのマニフェストファイルに、node_modulesの読み込みたいswiperファイルの名前を書きます。
app/assets/stylesheets/application.css.scss
@import 'swiper/swiper-bundle';
app/assets/javascripts/application.js
//= require swiper/swiper-bundle.js
swiperを実装
公式HPを参照し、HTMLとJSファイルを作成しましょう。現在(2021.11月)、swiperのバージョンは7系です。
バージョンによって書き方が異なるので注意が必要です。 今回はヘッダーファイルにJSごと作成していきます。
app/views/layouts/_header.html.slim
header
.swiper
.swiper-wrapper
- if current_site.main_images.present?
-current_site.main_images.each do |main_image|
= image_tag main_image,class: 'swiper-slide'
- else
= image_tag '/images/cover.jpg',class: 'swiper-slide'
.swiper-button-next # ナビゲーションボタン(→)
.swiper-button-prev # ナビゲーションボタン(←)
.swiper-pagination # ページネーション
.container.blog-title
h1 = link_to current_site.name, root_path
p.lead = current_site.subtitle
javascript:
$(document).ready(() => { // 画像などを除いて、HTML=DOMの読み込みが終わったら関数の中の処理を実行する
const swiper = new Swiper('.swiper', { // クラス指定
// Optional parameter
spaceBetween: 30, // スライド間の幅を指定
centeredSlides: true, // 中央寄せにする
autoplay: {
delay: 3000, // 切り替わり速度
disableOnInteraction: false, // ユーザーがスライダーを操作したあと、自動再生が止まらなくなる
},
// If we need pagination
pagination: {
el: ".swiper-pagination",
clickable: true,
},
// Navigation arrows
navigation: {
nextEl: '.swiper-button-next',
prevEl: '.swiper-button-prev',
},
// And if we need scrollbar
scrollbar: {
el: '.swiper-scrollbar',
},
})
});
必要があればCSS設定し、swiperのデザインを調整しましょう。
app/assets/stylesheets/application.css.scss
.swiper {
width: 600px;
height: 300px;
object-fit: cover;
}
画像削除処理のコントローラを作成する
画像削除の処理はparamsで条件分岐をせず、ActiveStorage::Attachmentから取得していること。
※ favicon, og_image, main_imagesはactive_storage_attachmentsテーブルにrecord_typeがSiteで登録されるので、
各idが一意である点を利用して削除対象のリソースを取得する。
app/controllers/admin/site/attachments_controller.rb
def destroy
authorize(current_site) # current_siteはSite.firstで対応できるが、今後の拡張を考慮して権限管理する
image = ActiveStorage::Attachment.find_by!(id: params[:attached_id])
image.purge
redirect_to edit_admin_site_path
end
画像削除処理のルーティングを作成する
config/routes.rb
# routingではadminsiteのresourceにnestさせて定義すると既存のアクションとの関連性が分かりやすい
namespace :admin do
resource :site, only: %i[edit update] do
resources :attachments, only: %i[destroy], module: :site
end
end
スライド画像用のパラメータをストロングパラメータに追加する
site_controller.rb
def site_params
params.require(:site).permit(:name, :subtitle, :description, :favicon, :og_image, <u>**main_images: []**</u>)
end
各画像の削除ボタンが追加する

app/views/admin/sites/edit.html.slim
.box.box-primary
= simple_form_for [:admin, @site], url: admin_site_path do |f|
.box-body
= f.error_notification
= f.input :name
= f.input :subtitle
= f.input :description, as: :text
= f.input :favicon, as: :file, hint: 'PNG (32x32)'
- if @site.favicon.attached?
= image_tag @site.favicon_url('32x32')
br
br
= link_to '削除', admin_site_attachment_path(@site.favicon.id), method: :delete, class: 'btn btn-danger'
br
br
= f.input :og_image, as: :file, hint: 'JPEG/PNG (1200x630)'
- if @site.og_image.attached?
= image_tag @site.og_image_url(:ogp), class: 'img-responsive'
br
br
= link_to '削除', admin_site_attachment_path(@site.og_image.id), method: :delete, class: 'btn btn-danger'
br
br
= f.input :main_images, as: :file, input_html: { multiple: true }, hint: 'JPEG/PNG (1200x400)'
#画像の複数アップロードのオプションの記載方法。
- if @site.main_images.attached?
.main_images_box
- @site.main_images.each do |image|
.main_image
= image_tag image.variant(resize:'1200x400').processed
= link_to '削除', admin_site_attachment_path(image.id), method: :delete, class: 'btn btn-danger'
Siteの画像の制限をかけておく
Siteの画像はadminユーザー以外は削除できないようにしておくことが望ましい。
app/policies/site_policy.rb
def destroy?
user.admin?
end