トップ画像をスライダー形式に変更
ActiveStorageとは
Amazon S3、Google Cloud Storage、Microsoft Azure Storageなどの クラウドストレージサービスへのファイルのアップロードや、ファイルをActive Recordオブジェクトにアタッチする機能を提供しています。
development環境とtest環境向けのローカルディスクベースのサービスを利用できるようになっており、ファイルを下位のサービスにミラーリングしてバックアップや移行に用いることもできる。
Active Storageの実装
# マイグレーションファイルを作成 rails active_storage:install # マイグレーションファイルを実行 rails db:migrate
Active Storageを使って、複数画像ファイルをアップロード
site.rb
class Site < ApplicationRecord # Active Storage の「1対1」の画像アップロード has_one_attached :og_image has_one_attached :favicon # Active Storage の「1対多」の画像アップロード has_many_attached :main_images
・スライド画像用のパラメータがストロングパラメータに追加されていること
site_controller.rb
private def site_params params.require(:site).permit(:name, :subtitle, :description, :favicon, :og_image, main_images: [])#最後追加 end
・各画像の削除ボタンが追加されていること
app/views/admin/sites/edit.html.slim
= 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)' = 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 |main_image| .main_image = image_tag main_image.variant(resize:'300x100').processed = link_to '削除', admin_site_attachment_path(main_image.id), method: :delete, class: 'btn btn-danger'
Active Storageでアップロードした画像を削除する
継承元を含めるコントローラーを生成するコマンド
bin/rails g controller Admin:Site:Attachments
admin/site/attachments_controller.rb
class Admin::Site::AttachmentsController < ApplicationController def destroy authorize(current_site) image = ActiveStorage::Attachment.find(params[:id]) image.purge redirect_to edit_admin_site_path end end
routes.rb
resource :site, only: %i[edit update] do resources :attachments, only: %i[destroy], controller: 'site/attachments' end
モデルにバリデーションを作成
site.rb
validates :og_image, attachment: { purge: true,content_type: %r{\Aimage/(png|jpeg)\Z}, maximum: 524_288_000 } validates :favicon, attachment: { purge: true,content_type: %r{\Aimage/(png|jpeg)\Z}, maximum: 524_288_000 } validates :main_images, attachment: { purge: true, content_type: %r{\Aimage/(png|jpeg)\Z},maximum: 524_288_000 }
app/validators/attachment_validator.rb
if options[:maximum] if value.is_a?(ActiveStorage::Attached::Many) # 画像が複数枚投稿された場合 value.each do |v| unless validate_maximum(record, attribute, v) has_error = true break end end else # 画像が1枚投稿された場合 has_error = true unless validate_maximum(record, attribute, value) end end if options[:content_type] if value.is_a?(ActiveStorage::Attached::Many) # 画像が複数枚投稿された場合 value.each do |v| unless validate_content_type(record, attribute, v) has_error = true break end end else # 画像が1枚投稿された場合 has_error = true unless validate_content_type(record, attribute, value) end end
・Siteの画像はadminユーザー以外は削除できないようにしておくこと
app/policies/site_policy.rb
def destroy? user.admin? end
Swiperとは
Swiperは「CSSやJS」を適用することで、画像のスライドを簡単に実装できる機能提供する「ライブラリ」です。
Swiper導入方法
設定方法として以下の3つあります。
①Swiperの公式サイトから必要なファイル(CSSやJS)をダウンロードしてアプリケーションに置いて、そいつを読み込む
②CDNを使って毎回クラウド上に公開したファイルにアクセスして取得する
③npm、yarnのJSのパッケージ管理ツールを使用する
今回はnpmでSwiperをインストールする手順と読込例です
npm install swiper
package.json
"dependencies": { "swiper": "^6.7.5", } `` config/initializers/assets.rb
Rails.application.config.assets.paths << Rails.root.join('node_modules')
node_modulesディレクトリまでのパスはデフォルトでは読み込んでくれないので、導入したnode_modulesディレクトリ以下のファイルを読み込むように設定を書きます。 app/asssets/javascripts/application.js
//= require swiper/swiper-bundle.js
上記のコードでnode_modules/swiper/swiper-bundle.jsファイルを application.jsファイルから読み込んでいます。 app/assets/stylesheets/application.css.scs
@import 'swiper/swiper-bundle';
application.css.scssファイルでnode_modules/swiper/swiper-bundle.cssファイルを読み込みます。 どうして読み込む必要があるかというと、JSファイルはスライダーの動きを使えるコードがswiper-bundle.jsファイルに記載されているからです。 また、デザインを当てるためにswiper-bundle.cssファイルを読み込む必要があります。 ## 必要なCSS app/assets/stylesheets/admin.css.scss
.main_images_box { display: flex; .main_image { text-align: center; padding: 1rem; img { display: block; margin-bottom: 1rem; } } }
assets/stylesheets/application.css.scss
header { position: relative;
.swiper-container { img { width: 100%; height: 400px; object-fit: cover; } }
.blog-title { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); color: white; z-index: 10; a { color: white; } } }
参考文献 [https://swiperjs.com/get-started:title] [https://weblog-tec.hatenablog.com/entry/2021/07/14/212732:title] [https://www.webdesignleaves.com/pr/plugins/swiper_js.html:title] [https://qiita.com/kenkentarou/items/bdf04d8ecab6a855e50f:title]