実現したいこと
PostモデルのFormにてGenreモデルのnameはuniquenessかつnameは空でもバリデーションに引っかからないようにしたい。そして空のデータは表示させたくない。
整理すると、
1. カラムはuniqueness、しかしカラムが空であった場合でもデータ送信ができる。
2. 空の状態を保存したものは出現させない。
課題
カラムが空であった場合データ送信ができる=空の場合uniquenessのバリデーションには引っかからないようにする。
解決策
条件付きバリデーションを作成する
前提
新規投稿を作るformに置いてPostモデルとGenreモデルの2つのデータ送信を同時に行いたい。
Formの一部(ここでPostモデルのFormでGenreモデルのデータも同時に送信)
<%= fields_for @genre, :genres do |form| %>
<%= form.label :新しくジャンルを作る %>
<%= form.text_field :name, class:"form-control" %>
<% end %>
Form全体
<div class="container">
<%= form_with(model: [:mypage, post], local: true) do |form| %>
<% if post.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(post.errors.count, "error") %> prohibited this post from being saved:</h2>
<ul>
<% post.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="form-group">
<%= form.text_field :title, class:"form-control", placeholder:"タイトル" %>
</div >
<div class="form-group">
<%= form.text_area :body, class:"form-control", placeholder:"自分の辞書をマークダウン記法で記入してみよう" %>
</div>
<div class="field">
<%= form.label :status %>
<%= form.select :status, Post.statuses.keys,class:"form-control" %>
</div>
<div class="field">
<%= form.label :posted_at %>
<%= form.datetime_select :posted_at %>
</div>
<div class="form-group">
<%= form.text_area :reason, class:"form-control", placeholder:"メモした経緯を書いてみよう" %>
</div>
<div class="field">
<%= form.label :rank %>
<%= form.select :rank, Post.ranks.keys, class:"form-control" %>
</div>
<div class="form-group">
<%= form.label :summary %>
<%= form.text_field :summary, class:"form-control" %>
</div>
<div class="form-group">
<%= form.label :URL %>
<%= form.text_field :url, class:"form-control" %>
</div>
<%= form.label :genre, 'ジャンル' %>
<%= form.collection_check_boxes(:genre_ids, current_user.genres.where.not(name:""), :id, :name) do |genre| %>
<%= genre.label do %>
<%= genre.check_box %>
<%= genre.text %>
<% end %>
<% end %><br>
<%= fields_for @genre, :genres do |form| %>
<%= form.label :新しくジャンルを作る %>
<%= form.text_field :name, class:"form-control" %>
<% end %>
<div class="actions">
<%= form.submit class:"btn btn-info" %>
</div>
<% end %>
</div>
Genreモデルでの条件付きバリデーションの作成
これによってから以外でuniquenessが発動するようになった
validates :name, uniqueness: true, unless: :name_check?
def name_check?
return true if self.name == ""
end
空は表示させない
where.not
<%= form.collection_check_boxes(:genre_ids, current_user.genres.where.not(name:""), :id, :name) do |genre| %>