質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.51%
Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Ruby on Rails 4

Ruby on Rails4はRubyによって書かれたオープンソースのウェブフレームワークです。 Ruby on Railsは「設定より規約」の原則に従っており、効率的に作業を行うために再開発を行う必要をなくしてくれます。

Q&A

解決済

1回答

3629閲覧

belongs_toの関係にあるインスタンスを保存するときのエラーメッセージについて

mntmnt

総合スコア14

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Ruby on Rails 4

Ruby on Rails4はRubyによって書かれたオープンソースのウェブフレームワークです。 Ruby on Railsは「設定より規約」の原則に従っており、効率的に作業を行うために再開発を行う必要をなくしてくれます。

0グッド

0クリップ

投稿2016/11/05 10:09

編集2016/11/05 10:54

###実現したいこと
ShopモデルとStaffモデルが1対多の関係を持っているとします。
@staff=Staff.newをsaveするとき、@staff.shop_idに不正な値が入っていた場合、
@staff.errors.messagesのkeyに:shop_idではなく:shopが指定されてしまいます。

formでエラーメッセージを表示させる都合上、
エラーメッセージのkeyには:shop_idが指定されてほしいのですが、
良い方法はありますでしょうか。

よろしくお願いいたします。
以下詳細です。

###前提

ShopモデルとStaffモデルが以下のような関連を持っているとします。

ruby

1class Staff < ActiveRecord::Base 2 belongs_to :shop, required: true 3end 4 5class Shop < ActiveRecord::Base 6 has_many :staffs 7end

Staffの登録フォーム画面は以下のようにしています。

html

1<%= form_for @staff do |f|%> 2 <%= f.label :name, '名前' %><br /> 3 <%= f.text_field :name, required: true %><br /> 4 <%= f.label :shop_id, '店舗' %><br /> 5 <%= f.collection_select :shop_id, Shop.all, :id, :name %><br /> 6<% end %>

###発生している問題

このとき、ブラウザ上のformでソースコードの書き換えなどを行い、
現在DBに登録されていないshop_idで登録しようとしたとき、
以下のようなerrorsが返されます。

ruby

1[1] pry(#<StaffsController>)> @staff.errors.messages 2=> {:shop=>["入力してください"]}>

エラータグを、フォームの適切な場所(今回はf.collection_selectの部分)に出力させたい都合上、
最低でも、以下のようなerror messagesを返してほしいと思っています。

ruby

1[1] pry(#<StaffsController>)> @staff.errors.messages 2=> {:shop_id=>["入力してください"]}>

画面をrenderする前に、無理やりエラーメッセージを書き換える方法や、
独自のバリデーションを実装する方法などが思い浮かんでいるのですが、
何かベストプラクティスはありますでしょうか?

よろしくお願いいたします。

###その他の情報

ちなみにコントローラーは以下です。

ruby

1 2def new 3 @staff = Staff.new 4end 5 6def create 7 @staff = Staff.new(create_params) 8 if @staff.save 9 redirect_to staff_path, notice: "新規追加しました" 10 else 11 render 'new' 12 end 13end 14 15private 16 17def create_params 18 params.require(:staff).permit(:name,:shop_id) 19end

###補足情報
以下のバージョンを利用しています。
Rails 4.2.4
ruby 2.2.3

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2016/11/05 10:39

うーん、view では店舗 ID ではなく、店舗名を選択させるのですよね? その際に『店舗 ID を入力して下さい』というメッセージを表示したいのでしょうか?
mntmnt

2016/11/05 10:52

コメントありがとうございます。目的は、登録formの店舗を選ぶセレクトボックスのところに、エラータグを出力させることです。メッセージの内容にはこだわりはありません。
退会済みユーザー

退会済みユーザー

2016/11/05 11:14

で、あれば :shop_id に拘らず、 :shop で実装しても良さそうですが、何故 :shop_id でなければならないのでしょうか?
mntmnt

2016/11/05 11:32

コメントありがとうございます。私の力不足なのですが「:shopで実装する方法」というのが理解できておりません。何かサンプルコードなどがありましたらご教示頂けますでしょうか?
mntmnt

2016/11/06 10:34

ありがとうございます。少し試行錯誤してみます。
guest

回答1

0

ベストアンサー

ruby

1class Staff < ActiveRecord::Base 2 belongs_to :shop 3 validates :shop_id, presence: true 4end

かな。
と、思いましたが shop_id の shop が存在するかを確認したいのですね。。。。
カスタムメソッドによるカスタムバリデーションが一番簡単だと思います。

ruby

1class Staff < ActiveRecord::Base 2 belongs_to :shop 3 validate :shop_id_is_valid 4 5 def shop_id_is_valid 6 errors.add(:shop_id) unless Shop.find_by(id: shop_id) 7 end 8end

投稿2016/11/08 22:29

編集2016/11/08 22:39
hana-da

総合スコア1728

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

mntmnt

2016/11/12 06:00

やはりカスタムバリデーションが一般的ですかね! ご回答ありがとうございます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.51%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問