Validate presence of notes.content
This commit adds both model and controller coverage for validating that
Note model is created with its required fields.
Extends the Note model to use the
validates_presence_of validator by passing
presence: true to the validates macro .
When validating a record without a content field, the presence: true
validation’s failure supersedes the previous behavior of violating the
column’s NOT NULL constraint and raising a
ActiveRecord::NotNullViolation error. Since the two are not
compatible, this commit removes the previous test coverage from
notes_test.rb.
When responding to a POST /notes request that would result in an
invalid Note record, our controller will re-render the notes#new to
present the client with another opportunity to submit a Note. In
addition, the controller will respond with a 422 HTTP Status to
indicate to the client that the previous request was unprocessable
entity.
Collapse app/controllers/notes_controller.rb
Expand app/controllers/notes_controller.rb
app/controllers/notes_controller.rb
diff --git a/app/controllers/notes_controller.rb b/app/controllers/notes_controller.rb
index 7534670..8375672 100644
--- a/app/controllers/notes_controller.rb
+++ b/app/controllers/notes_controller.rb
@@ -8,8 +8,18 @@ class NotesController < ApplicationController
end
def create
- note = Note.create!(params.to_unsafe_h.slice(:content))
+ note = Note.new(note_params)
- redirect_to notes_url
+ if note.save
+ redirect_to notes_url
+ else
+ render(:new, status: :unprocessable_entity)
+ end
+ end
+
+ private
+
+ def note_params
+ params.to_unsafe_h.slice(:content)
end
end
Collapse app/models/note.rb
Expand app/models/note.rb
app/models/note.rb
diff --git a/app/models/note.rb b/app/models/note.rb
index b6b1e5a..67129f0 100644
--- a/app/models/note.rb
+++ b/app/models/note.rb
@@ -1,2 +1,3 @@
class Note < ApplicationRecord
+ validates :content, presence: true
end
Collapse test/controllers/notes_controller_test.rb
Expand test/controllers/notes_controller_test.rb
test/controllers/notes_controller_test.rb
diff --git a/test/controllers/notes_controller_test.rb b/test/controllers/notes_controller_test.rb
index eebcb0a..2d64375 100644
--- a/test/controllers/notes_controller_test.rb
+++ b/test/controllers/notes_controller_test.rb
@@ -10,10 +10,18 @@ class NotesControllerTest < ActionDispatch::IntegrationTest
end
test "#create redirects to /notes" do
- notes_attributes = { content: "Hello, World" }
+ note_attributes = { content: "Hello, World" }
- post notes_path, params: notes_attributes
+ post notes_path, params: note_attributes
assert_redirected_to notes_url
end
+
+ test "#create with invalid data responds with unprocessable entity" do
+ note_attributes = {}
+
+ post notes_path, params: note_attributes
+
+ assert_response :unprocessable_entity
+ end
end
Collapse test/models/note_test.rb
Expand test/models/note_test.rb
test/models/note_test.rb
diff --git a/test/models/note_test.rb b/test/models/note_test.rb
index 42a53e2..679348d 100644
--- a/test/models/note_test.rb
+++ b/test/models/note_test.rb
@@ -1,11 +1,12 @@
require 'test_helper'
class NoteTest < ActiveSupport::TestCase
- test "NOT NULL database constraint on notes.content" do
+ test "validates content is present" do
note = Note.new
- exercise = -> { note.save! }
+ valid = note.validate
- assert_raises(ActiveRecord::NotNullViolation, /content/, &exercise)
+ assert_equal valid, false
+ assert_equal note.errors[:content], [I18n.translate("errors.messages.blank")]
end
end