質問: "記事を作成しました" redirect_to articles_url else render 'articles/new' end ``` `save_tags`メソッドの中で、バリデーションを行い(個数制限や文字数制限など)、 `error.add`でエラーを追加。エラーだと`false`を返すようにしています。 エラーメッセージの追加方法は以下のような感じ。 ``` errors.add(:tag_list, "タグの個数がオーバーしています。") if tags.count > 5 ``` この際、(当然なのですが)まず最初にArticleモデルのバリデーションが行われて、その後にTagのチェックが行われます。 つまり、まずArticleモデルのバリデーションをクリアしないとタグのエラーメッセージは表示されません(Articleモデルのバリデーションをクリアした場合、Tagのエラーメッセージが表示されます)。 例えば、Articleのタイトルがない状態で、かつ、タグが7個以上登録されている場合、エラーメッセージは ・Articleのタイトルが空です。 のみが表示されて、タグのバリデーション結果は表示されません。 希望としては、 ・Articleのタイトルが空です。 ・タグの個数がオーバーしています。 を同時に出力したいです。 これはどのようにすれば実現するでしょうか? 割とよくある形のような気がするのですが素人すぎて検索方法もわからず、、 ご教示頂けましたら幸いです。 よろしくお願いいたします。
回答: コメントですでに解決している様子ですが、回答にまとめます。 今回問題になっているのは、最初のレコード保存である `@article.save` が失敗したときに、 `@article.save && @article.save_tags(tag_list)` のうち後半部分の `save_tags` が実行されず、結果、バリデーションを実行したならば追加されていたであろうエラーたちが、 errors に追加されないことが問題です。 ruby において `&&`, `||` オペレーターは、その評価の際にショートサーキットという処理が行われます。何かと言うと、この2項演算子の最初の引数の時点で式の返り値が確定する場合、2つめの引数の評価を行わない、という処理です。 具体例でいうと、以下はエラーになりません。 ``` true || raise false && raise ``` さて、今回の件では、むしろそのショートサーキットが邪魔で、ただただ両方を実行してその結果を and したい、が要件です。 そして、 ruby において、それを実現するためには、 `&` と `|` が利用できます。その実、これらはただの `TrueClass`, `FalseClass` のメソッドとして定義されていて、なので、通常の2項演算子と同じように、 1. 第一引数の評価 2. 第二引数の評価 3. オペレーター自体の演算処理(メソッド呼び出し) の順で実行されます。 ### 参考 * * > > there is no short-circuit evaluation in this case. > > — `ri 'FalseClass#&'` > > >