🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
Ruby on Rails

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

バリデーション

Validationとは特定の入力データが、求められた条件に当てまっているかをチェックするために使われます。

保存

保存(save)とは、特定のファイルを、ハードディスク等の外部記憶装置に記録する行為を指します。

Active Record

Active Recordは、一つのオブジェクトに対しドメインのロジックとストレージの抽象性を結合するデザインパターンです。

Q&A

2回答

674閲覧

Railsのバリデーションに関する質問です!

sn.jr

総合スコア53

Ruby on Rails

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

バリデーション

Validationとは特定の入力データが、求められた条件に当てまっているかをチェックするために使われます。

保存

保存(save)とは、特定のファイルを、ハードディスク等の外部記憶装置に記録する行為を指します。

Active Record

Active Recordは、一つのオブジェクトに対しドメインのロジックとストレージの抽象性を結合するデザインパターンです。

0グッド

1クリップ

投稿2019/12/29 01:29

質問

現在、投稿(Postモデル)のジャンル(Genreモデル, nameカラム)分けを行いたく、中間モデルManageを用いて作成しています。** schema.rbは下に明記しています! **
そこでGenreモデルのバリデーションに関する質問なのですが、Genreモデルにはnameというカラムがありそこにジャンル名を入れるのですが、今の仕様だと空欄(nil)もジャンル名として保存されてしまいます。今まではそこでvalidates :name, presence: trueにして対応してきましたが、「ジャンル名は空欄でも良い」仕様にしたいです。
整理すると
Genreモデルのnameに空欄は保存させたくないが、nameが空欄でもフォームは送信できるようにしたい。
nilというデータでの保存を防ぎたい

少し説明が難しく、わかりづらい文章になってしまっているので質問などしていただけると幸いです!

rb

1class Genre < ApplicationRecord 2 has_many :manages 3 has_many :posts, through: :manages 4 validates :name, uniqueness: true

rb

1ActiveRecord::Schema.define(version: 2019_12_28_045120) do 2 3 create_table "genres", force: :cascade do |t| 4 t.string "name" 5 t.integer "status" 6 t.datetime "created_at", precision: 6, null: false 7 t.datetime "updated_at", precision: 6, null: false 8 end 9 10 create_table "manages", force: :cascade do |t| 11 t.integer "genre_id" 12 t.integer "post_id" 13 t.datetime "created_at", precision: 6, null: false 14 t.datetime "updated_at", precision: 6, null: false 15 t.index ["genre_id"], name: "index_manages_on_genre_id" 16 t.index ["post_id"], name: "index_manages_on_post_id" 17 end 18 19 create_table "posts", force: :cascade do |t| 20 t.string "title" 21 t.text "body" 22 t.datetime "posted_at" 23 t.text "reason" 24 t.integer "rank" 25 t.string "summary" 26 t.datetime "created_at", precision: 6, null: false 27 t.datetime "updated_at", precision: 6, null: false 28 t.integer "status" 29 t.string "url" 30 end 31 32 create_table "users", force: :cascade do |t| 33 t.string "email", default: "", null: false 34 t.string "encrypted_password", default: "", null: false 35 t.string "reset_password_token" 36 t.datetime "reset_password_sent_at" 37 t.datetime "remember_created_at" 38 t.datetime "created_at", precision: 6, null: false 39 t.datetime "updated_at", precision: 6, null: false 40 t.index ["email"], name: "index_users_on_email", unique: true 41 t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true 42 end 43 44end

投稿とジャンルを保存するフォーム

rb

1<div class="container"> 2<%= form_with(model: [:mypage, post], local: true) do |form| %> 3 <% if post.errors.any? %> 4 <div id="error_explanation"> 5 <h2><%= pluralize(post.errors.count, "error") %> prohibited this post from being saved:</h2> 6 7 <ul> 8 <% post.errors.full_messages.each do |message| %> 9 <li><%= message %></li> 10 <% end %> 11 </ul> 12 </div> 13 <% end %> 14 <div class="form-group"> 15 <%= form.text_field :title, class:"form-control", placeholder:"タイトル" %> 16 </div > 17 <div class="form-group"> 18 <%= form.text_area :body, class:"form-control", placeholder:"自分の辞書をマークダウン記法で記入してみよう" %> 19 </div> 20 21 <div class="field"> 22 <%= form.label :status %> 23 <%= form.select :status, Post.statuses.keys,class:"form-control" %> 24 </div> 25 26 <div class="field"> 27 <%= form.label :posted_at %> 28 <%= form.datetime_select :posted_at %> 29 </div> 30 31 <div class="form-group"> 32 <%= form.text_area :reason, class:"form-control", placeholder:"メモした経緯を書いてみよう" %> 33 </div> 34 35 <div class="field"> 36 <%= form.label :rank %> 37 <%= form.select :rank, Post.ranks.keys, class:"form-control" %> 38 </div> 39 40 <div class="form-group"> 41 <%= form.label :summary %> 42 <%= form.text_field :summary, class:"form-control" %> 43 </div> 44 45 <div class="form-group"> 46 <%= form.label :URL %> 47 <%= form.text_field :url, class:"form-control" %> 48 </div> 49 50 <%= form.label :genre, 'ジャンル' %> 51 <%= form.collection_check_boxes(:genre_ids, Genre.all, :id, :name) do |genre| %> 52 <%= genre.label do %> 53 <%= genre.check_box %> 54 <%= genre.text %> 55 <% end %> 56 <% end %><br> 57 <%= fields_for @genre, :genres do |form| %> 58 <%= form.label :新しくジャンルを作る %> 59 <%= form.text_field :name, class:"form-control" %> 60 <% end %> 61 62 <div class="actions"> 63 <%= form.submit class:"btn btn-info" %> 64 </div> 65<% end %> 66</div>

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

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

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

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

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

guest

回答2

0

何をしたいのか、が正確に伝わるようにしましょう

validates :name, uniqueness: true, if: :present?

かな

投稿2019/12/30 02:20

winterboum

総合スコア23567

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

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

0

今でも、
1)nameが空欄でもformの送信ができる
2)nameがnilでの保存は防ぐ
はできていると思います。
何が足りないのでしょう?
もしかすると
3)nilでの保存は出来ないが空文字列で保存したい
でしょうか
3')nilで送られてきたら空文字列で保存する
でしょうか。
なお、
nameが空欄の場合ブラウザはnameを送りません。ですのでRails側がnameを参照するとnilになります。
nilは送らない、空欄を送る というのは出来ません。
JS使えばできるのかもしれませんが、意味ないのでやったことはないです。

ああ、『空欄は保存したくない」ですね。
すると送られてきたformはどのように処理したいのでしょう???

投稿2019/12/29 01:59

編集2019/12/29 02:02
winterboum

総合スコア23567

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

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

sn.jr

2019/12/29 04:39

ご回答ありがとうございます!空欄というのはnilのことを示してました。つまりnilでもデータを送ることはできるが、name: nilとして保存させたくないということです。その理由としてnameはuniquenessであるため、nilを一度保存してしまうと、それ以降nilでの保存つまりnameを空欄にして送信することができなくなってしまうからです。
winterboum

2019/12/29 07:11

しかし、空欄(空文字)を入れても uniqunessに引っかかりますよ? 空欄を許し、かつ空欄以外ではuniquである としたい?
sn.jr

2019/12/30 01:02

そうなんです。おっしゃる通り、空欄を許し、かつ空欄以外ではuniquを目指してます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問