@seiyarick (seiya)

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

バリデーションのエラーメッセージについて

Q&A

Closed

追記

エラーメッセージを日本語にする事はできました。
解決方法は
「ja.yml」のファイル名を「devise.ja.yml」に変更することで日本語化に成功しました。

スクリーンショット 2022-04-23 11.27.42.png

ですが料理画像に関してのエラーメッセージが出てきません。
料理名、紹介文を入力して料理画像を登録しない状態で投稿すると以下のようなエラーが出てきます。
バリデーションのエラーメッセージに表示させるにはどうすれば良いでしょうか?
教えていただきたいです。
よろしくお願いします。
スクリーンショット 2022-04-23 11.32.37.png

解決したいこと

エラーメッセージを「料理名」「料理画像」「紹介文」についての3項目で表示したいが「料理画像」以外の内容が表示される。
バリデーションのエラーメッセージを日本語で表示したいです。

発生している問題・エラー

・enumを使い日本語でエラーメッセージを表示させたところ以下のような表示になり完全に日本語で表示されない。

・料理画像が選択されていないことに関してのエラーメッセージが表示されていない。

スクリーンショット 2022-04-22 14.39.49.png

該当するソースコード

*/CookOP/config/application.rb

module CookOP
  class Application < Rails::Application
    # Settings in config/environments/* take precedence over those specified here.
    # Application configuration should go into files in config/initializers
    # -- all .rb files in that directory are automatically loaded.
  config.i18n.default_locale = :ja
  config.i18n.load_path += Dir[Rails.root.join('config/locales/*.yml').to_s]
  end

*/CookOP/config/locales/ja.yml

ja:
 enums:
  dish:
   dish_name: "料理名"
   introduction: "紹介文"
   dish_image: "画像"

*/CookOP/app/views/dishes/new.html.erb

<%= form_with model: @dish, url: dishes_path(current_user.id), method: :post do |f|  %>
      <% if @dish.errors.any? %>
      <div class="row justify-content-center">
        <div class="alert alert-warning">
        <%= @dish.errors.count %>件のエラーが発生しました
        <ul>
          <% @dish.errors.full_messages.each do |message| %>
            <li><%= message %></li>
          <% end %>
        </ul>
        </div>
      </div>
      <% end %>
      <div class="row mb-4">
        <%= f.label "料理名", class:"col-4 col-form-label text-center" %>
        <%= f.text_field :dish_name, class:"col-8 form-control", placeholder:"料理名を入力してください。" %>
      </div>
      <div class="row mb-4">
        <%= f.label "料理画像", class:"col-4 col-form-label text-center" %>
        <%= f.file_field :dish_image, accept: "image/*" %>
      </div>
      <div class="row mb-4">
        <%= f.label "紹介文", class:"col-4 col-form-label text-center" %>
        <%= f.text_area :introduction,
        placeholder:"使用した食材や料理の作り方を書いてみんなにシェアしてください。右下の角を下に引っ張ると記入欄が大きくなります。",
        class:"col-8 form-control" %>
      </div>
      <div class="row">
        <div class="col-12 text-right">
        <%= f.submit "CookOPする",class:"btn btn-light" %>
        </div>
      <% end %

*/CookOP/db/schema.rb

create_table "dishes", force: :cascade do |t|
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.integer "user_id"
    t.string "dish_name"
    t.text "introduction"
  end

*/CookOP/app/models/dish.rb

class Dish < ApplicationRecord
  has_one_attached :dish_image
  belongs_to :user#, optional: true
  has_many :comments, dependent: :destroy
  has_many :favorits, dependent: :destroy

  validates :dish_name, presence: true
  validates :introduction, presence: true
  validates :dish_image, presence: true

*/CookOP/app/controllers/dishes_controller.rb

class DishesController < ApplicationController

  def new
    @dish = Dish.new

  end

  def ranking
    @all_ranks = Dish.create_all_ranks

  end


  def index
    # @dishes = Dish.all
    @q = Dish.ransack(params[:q])
    @searchs = @q.result(distinct: true).order("id DESC")
  end

  def edit
    @dish = Dish.find(params[:id])
  end

  def show
    @dish = Dish.find(params[:id])
    @comment = Comment.new

    @comments = @dish.comments

  end

  def create
    @dish = Dish.new(dish_params)
    if @dish.save
      redirect_to user_path(current_user.id)
    else
      render :new
    end
  end

  def update
    dish = Dish.find(params[:id])
    if dish.update(dish_params)
      redirect_to dish_path(dish.id)
    else
      render :edit
    end
  end

  def confirm

  end

  def search
    @q = Dish.ransack(params[:q])
   @dishes = @q.result(distinct: true)
  end

  def destroy
        @dish = Dish.find(params[:id])
        if @dish.destroy
            redirect_to user_path(@dish.user_id)
        else
            render :edit
        end
  end

  private

  def dish_params
    params.require(:dish).permit(:dish_name, :introduction, :user_id, :dish_image).merge(user_id: current_user.id)

  end

end

自分で試したこと

エラーメッセージで「を入力してください」は日本語になっているのでymlファイルの記述が間違えているのかと思っていたのですがどこが間違えているかわかりませんでした。


説明の不足している点などありましたら教えていただきたいです。

よろしくお願いします。

0 likes

1Answer

スクリーンショット 2022-04-23 16.17.15.png

dishesテーブル内にdish_imageカラムがないからだと思います。
それともdish_imageカラムは別テーブルに保存しているのでしょうか?
されていないのであればdishesテーブルにdish_imageカラムを追加して再度検証してみてはいかかでしょう

0Like

Comments

  1. @seiyarick

    Questioner

    @daigo01090118 さん
    コメントしていただきありがとうございます。
    以下のようにテーブルに追加して試して見ましたがダメでした。dish_imageカラムはdishesテーブルだけになります。
    ```ruby
    create_table "dishes", force: :cascade do |t|
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.integer "user_id"
    t.string "dish_name"
    t.string "dish_image"
    t.text "introduction"
    end
    ```
  2. 大変申し訳ありません、railsのactive_storageを使用されていたのですね、
    それであればdishesテーブルにdish_imageを格納する必要はありませんね、
  3. ちゃんと保存先を設定しているのであれば、バリデーションが効かないことはあり得ないので
    原因はactive_storageの方にあると思います。
    調べたところ、active_storageにはvalidationに相当するものがないみたいです。
    使用するには以下のgemをインストールしてください

    gem 'active_storage_validations'

    その後、該当のカラム(dish_image)に対して

    validates :dish_image, attached: true, content_type: [:png, :jpg, :jpeg]
    みたいな記述で実装できるみたいです

    公式のドキュメントを読んできましたが、presence: trueに該当するものが見つからなかったため
    上記のcontent_typeでバリデーションをかけるのがいいかなと思いました。

    理由としましては、
    dish_imageがNULLを認めないのであれば必ずpng or jpgのようなファイルが選択されるはずです。
    その形式以外のファイルが送信された時に発動するようにしたいからです。

    例えばデフォルトで適当なファイル(pngでもjpgでもないファイル)を送信するように書いておくとかでしょうか。

    これで上手くいかないのであれば申し訳ありませんがお力になれそうにありません。
    この方法でご検討よろしくお願いします
  4. @seiyarick

    Questioner

    @daigo01090118 さん

    質問内容の中でactive_storageを使用している説明が抜けていました、、、
    お手数お掛けしてすいません。

    説明していただいたgem 'active_storage_validations'をインストールするやり方を試して見たところエラーメッセージに画像に関しての内容が表示されました!!

    原因がactive_storageにあり別のgemをインストールすることは考えていなかったです。

    content_typeという記述を初めて見ましたし知らないことばかりでとても勉強になりました。
    もっと躓いて幅広く理解できるようにしていきます。

    ありがとうございました。
    また機会があればよろしくお願いします。

Your answer might help someone💌