I'm writing a Rails integration test that checks that the user's title saves. The title has one validation: it has to be no more than 255 characters. But @user.update_attributes!(title: params[:title])
is throwing the error "Password must have at least 6 characters." But...I'm not updating the password or anything other than the title. So how do I save this attribute with its own validation and not worry about the password?
Test:
test "profile submits new title and description successfully" do
log_in_as(@non_admin)
get user_path(@non_admin)
assert_nil @non_admin.title
post "/users/#{@non_admin.id}/update_description",
{ title: "I am a man of constant sorrow." }
user = assigns(:user)
user.reload.title
assert user.title == "I am a man of constant sorrow."
assert_template 'users/show'
assert flash[:success]
end
Controller method (not finished, but you'll get the idea). Note, it's the update_attributes!
call that throws the password validation error.
# Handles user's posted title and description.
def update_description
@user = User.find(params[:id])
# Check if title is present. If so, attempt to save, load flash, and reload.
if @user.update_attributes!(title: params[:title])
flash[:success] = "Saved title. "
# if unable, set error flash and reload.
else
flash[:warning] = "Unable to save."
end
# Same logic as before, now for description.
# Make sure two different [:success] flashes work! Probably not!
redirect_to user_path(@user)
end
Validations:
validates :password, length: { minimum: 6,
message: "must have at least 6 characters" }
validates :title, length: { maximum: 255 }
Here's the test error:
23:08:51 - INFO - Running: test/integration/users_show_test.rb
Started
ERROR["test_profile_submits_new_title_and_description_successfully", UsersShowTest, 2017-10-23 01:06:11 -0400]
test_profile_submits_new_title_and_description_successfully#UsersShowTest (1508735171.57s)
ActiveRecord::RecordInvalid: ActiveRecord::RecordInvalid: Validation failed: Password must have at least 6 characters
app/controllers/users_controller.rb:71:in `update_description'
test/integration/users_show_test.rb:22:in `block in <class:UsersShowTest>'
app/controllers/users_controller.rb:71:in `update_description'
test/integration/users_show_test.rb:22:in `block in <class:UsersShowTest>'
In case it's relevant, here's the fixture that is loaded as @non_admin
:
archer:
name: Sterling Archer
email: [email protected]
password_digest: <%= User.digest('Jsdfuisd8f') %>
activated: true
activated_at: <%= Time.zone.now %>
I'm a Rails noob so it's probably something basic. Thanks in advance...
UPDATE: See discussion with kasperite below. I simply needed to add on: create
to my password validation.
Calling update_attributes!
will triggers save!
, which in turn triggers validation on the model. And since you don't provide password, it will throw the exception.
You can either do update_attribute(:title, params[:title])
which bypass validation
or this:
@user.title = params[:title]
@user.save!(validation: false)
See: http://api.rubyonrails.org/classes/ActiveRecord/Persistence.html#method-i-update-21