Ryota400’s blog

エンジニアを目指して書いてます。

アイキャッチの表示サイズ / 位置指定

実装したいこと

アイキャッチ画像をユーザーの入力した幅に設定したい。

アイキャッチ画像をユーザーの選択した位置に設定したい。

Image from Gyazo

アイキャッチとは

投稿ページの記事タイトルの下に表示される画像のこと

画像の表示サイズの設定

カラム追加

rails g migration AddColumnToArticles  eyecatch_width:integer#画像幅 eyecatch_align  :integer#画像位置
class AddImageInfoToArticles < ActiveRecord::Migration[5.2]
  def change
    add_column :articles, :eyecatch_align, :integer, default: 0, null: false
    add_column :articles, :eyecatch_width, :integer
  end
end

eyecatch_width (横幅用のカラム)のデフォルトを100にするが、カラムにデフォルトを追加すると変更するときに大変になるので、ここでは設定しない。

ayacatch_align (位置用のカラム) defaul:0やnul:falseを追加することで、記事作成でバリテーションエラーとなる。

rails db:migrate

モデルに対して Active Storage用の設定を追加

<一つのファイルを選択する>

has_one_attached :カラム名

<複数のファイルを選択する>

has_many_attached :カラム名

<今回の場合>
article.rb

has_one_attached :eye_catch

enum設定

enum eyecatch_position: { left: 0, center: 1, right: 2 }
#上記で左寄せ・中央寄せ・右寄せの3択で設定

Validation設定
articles.rb

validates :eyecatch_width, numericality: { less_than_or_equal_to: 700, greater_than_or_equal_to: 100 }, allow_blank: true

ユーザーの入力値は、100~700pxに限定します。 空欄を許可しておかないと、アイキャッチ画像を設定せずに更新したいときにもバリデーションエラーになるので必須の設定

・less_than_or_equal_to
指定された値と等しいか、それよりも小さくなければならないことを指定する。

デフォルトで「must be less than or equal to %{count}」というエラーメッセージを返す。

・greater_than_or_equal_to:
指定された値と等しいか、それよりも大きくなければならないことを指定する。

デフォルトで「must be greater than or equal to %{count}」というエラーメッセージを返す。

・allow_blank: true
値が空の場合はバリデーションをパスする。

入力フォーム作成

articles/edit.html.slim

            = image_tag @article.eye_catch_url(:thumb), class: 'img-thumbnail'
            br
            br
      = f.input_field :eyecatch_align, as: :radio_buttons    #デフォルトの100。ここでvalidatesでallow_blank: trueにしているので、blankの際は100が入る。
      = f.input :eyecatch_width, placeholder: '100'

このようなHTMLが作成される。

<span class="radio radio radio">
<label for="article_eyecatch_position_left"><input class="enum_radio_buttons optional" type="radio" value="left" name="article[eyecatch_position]" id="article_eyecatch_position_left" />左寄せ
</label></span>
<span class="radio radio radio">
<label for="article_eyecatch_position_center"><input class="enum_radio_buttons optional" type="radio" value="center" checked="checked" name="article[eyecatch_position]" id="article_eyecatch_position_center" />中央寄せ
</label></span>
<span class="radio radio radio">
<label for="article_eyecatch_position_right"><input class="enum_radio_buttons optional" type="radio" value="right" name="article[eyecatch_position]" id="article_eyecatch_position_right" />右寄せ
</label></span>

画像表示部分のclassを動的に変更

views/shared/_article.html.slim

- if article.eye_catch.attached?
    section class="eye_catch text-#{article.eyecatch_align}"    #enumを使用し位置指定
        = image_tag article.eye_catch_url(:lg), class: 'img-fluid', width: article.eyecatch_width      #eyecatch_widthを使用して横幅指定

class="text-right" class="text-center" class="text-left"を使用すれば、enumの値をそのまま使用できる。
画像幅は、保存した値をarticle.eyecatch_widthでそのまま取ってこれる。

Controller設定

(admin/articles_controller.rb)

def article_params
    params.require(:article).permit(
      :title, :description, :slug, :state, :published_at, :eye_catch, :category_id, :eyecatch_position, :eyecatch_width, :author_id, tag_ids: []
    )
# 上記に:eyecatch_positionと :eyecatch_widthを追記
  end

日本語設定

activerecord.ja.yml

 eyecatch_align: '位置'
 eyecatch_width: '横幅'

enums.ja.yml

   eyecatch_align:
        left: '左寄せ'
        center: '中央'
        right: '右寄せ'

参考文献

bon-voyage23.hatenablog.com