Rails "Not Null Constraint" and "Validation (presence: true)" Note

While studying, I noticed that there is a difference between the two movements I also found an article by Qiita that is being investigated for similar content. I would like to summarize it as a memo while checking the operation even in my own local

First, create a simple app for posting

rb:app/controller/posts.controller.rb


class PostsController < ApplicationController
  def index
    @posts = Post.where(user_id: @user.id)
  end

  def new
    @posts = Post.new
  end

  def crate
    @posts = Post.create(
      title: params[:post][:title],
      contents: params[:post][:contents],
      user_id: @user.id
    )

    if @posts.save
      redirect_to posts_index_path
    else
      render :new
    end
  end
end

Migration file

db/migrate/☓☓☓_create_posts.rb


class CreatePosts < ActiveRecord::Migration[5.2]
  def change
    create_table :posts do |t|
      t.string :title, null: false
      t.text :contents
      t.string :user_id

      t.timestamps
    end
  end
end

Table * Marked with * for easy understanding

sqlite> .schema posts

CREATE TABLE IF NOT EXISTS "posts" (
"id" integer NOT NULL PRIMARY KEY, 
"title" varchar NOT NULL, 
"contents" text DEFAULT NULL, 
"user_id" integer DEFAULT NULL, 
"created_at" datetime NOT NULL, 
"updated_at" datetime NOT NULL);

The title has a "** NOT NULL **" constraint Try posting with an empty title

~/environment/rails/sample_app
❯ rails c
Running via Spring preloader in process 23513
Loading development environment (Rails 5.2.4.4)
[1] pry(main)> Post.all
  Post Load (1.1ms)  SELECT "posts".* FROM "posts"
=> []

Make sure the contents are not filled

rb:app/views/posts/new.html.erb


<h1>Post new creation screen</h1>

<%= form_with(model: @posts, url: posts_crate_path, local: true) do |f| %>
  <%= f.text_field :title %>
  <%= f.text_area :contents %>

  <%= f.submit 'To confirmation screen' %>
<% end %>

Try typing with the title empty

If you try typing empty and check the console

~/environment/rails/sample_app
❯ rails c
[2] pry(main)> Post.all
  Post Load (1.6ms)  SELECT "posts".* FROM "posts"
=> [#<Post:0x00007f956380e990
  id: 1,
  title: "",
  contents: "Test contents",
  user_id: 1,
  created_at: Mon, 28 Dec 2020 07:43:20 UTC +00:00,
  updated_at: Mon, 28 Dec 2020 07:43:20 UTC +00:00,
  posted_date: nil>]

Turned out to be preserved

"With NOT NULL constraint" ...

Cannot reject "empty string (" ")" So it will be saved like this time

"Null" and "empty string (" ")" are completely different

Difference between "null" and "empty string (" ")"

"Null" or "nil" in Ruby is ... ・ Treated as "** false **" in the same way as false · ** NilClass ** instance ・ Nothing in the container or contents **

"Empty string (" ")" is ... ・ "" Has ** blanks **

If you want to reject the empty string ...

Give the model validation

app/models/user.rb


class Post < ApplicationRecord
  belongs_to :user

  #Reject the empty string
  validates :title, presence: true
end

If you set the above, you don't have to enter anything in the form (empty string) Will not be reflected in the data

Reference article

https://qiita.com/wonder_meet/items/fa804f0d436a29c97460 https://qiita.com/tsuchinoko_run/items/c9214379a1f2878ec4ee

Recommended Posts

Rails "Not Null Constraint" and "Validation (presence: true)" Note
Difference between Not Null constraint and model validation (presence: true)
Add Not null constraint after Rails
Rails validation and null: false Personal notes
[Rails] Validation settings and Japanese localization
[Rails] [Memo] When to add = to <%%> and when not
A note about the Rails and Vue process