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