Reputation: 693
I am using the same commands that I previously used in successful projects but now I suddenly can't validate any updates to the object(in this case, User). Everything else works fine but any attempt to check my validations for an update results in this error-
'undefined method `valid?' for # '
It is finding successfully finding the user and if I skip the .valid? statement then it will update, just without checking any of my model validations. I recently switched from SQLite to PostgreSQL, I am not sure if that's giving me the problem. I am new to Ruby but I couldn't find anything on this specific problem.
Please let me know if I should include the entirety of my controller or any of my model but as my create works fine, I feel like all the relative code is just in this little section-
class UsersController < ApplicationController
def update
@user = User.find(params[:id])
puts "#Is this working???!! #{@user}" ///prints #Is this working???!! #<User:0x00000001f24468>
@user = User.update(user_params)
if @user.valid?
redirect_to "/users/#{@user.id}"
else
flash[:errors] = @user.errors.full_messages
redirect_to "/users/#{@user.id}/edit"
end
end
private
def user_params
params.require(:user).permit(:name, :email, :password)
end
Upvotes: 0
Views: 666
Reputation: 140
ActiveRecord update(id, attributes)
Updates an object (or multiple objects) and saves it to the database, if validations pass. The resulting object is returned whether the object was saved successfully to the database or not.
Then, you can do this checking if @user.update(user_params)
def update
@user = User.find(params[:id]) # Find user
if @user.update(user_params) # Update user if validations pass
redirect_to "/users/#{@user.id}"
else
flash[:errors] = @user.errors.full_messages
redirect_to "/users/#{@user.id}/edit"
end
end
Or, you can call the update method directly in your model class, but the first argument must be the user ID
User.update(params[:id], user_params)
Upvotes: 0
Reputation: 693
Thank you both for your quick answers. I was replying to tell you that I already tried that and it worked but did not validate. But as two of you told me the same thing, I decided to test it out again and the validations did indeed work this time so thank you (although I definitely have a user with an email of 'asdf' from last time).
Intestering enough, I found another answer although I have no idea why it worked. I added another puts statement after the update and realized my object had been converted to an array so I came up with this other (worse) alternative answer-
def update
@user = User.find(params[:id])
puts "#Is this working???!! #{@user}"
@user = User.update(user_params)
puts "#Is this working???!! #{@user}" ///prints #Is this working???!! [#<User id: 2, name: "James Dean", etc..>]
if @user[0].valid?
redirect_to "/users/#{@user[0].id}"
else
flash[:errors] = @user[0].errors.full_messages
redirect_to "/users/#{@user[0].id}/edit"
end
end
Upvotes: 0
Reputation: 6455
Your problem is here:
@user = User.update(user_params)
If you put in your check after, you would see: #Is this working???!! true
, which would ironically enough inform you that it's not working.
That's because User.update(user_params)
returns true or false depending on whether it is successful or not. This means your @user
object is now simply either true or false, which you can't call valid
on.
If you want to handle successfully updating / failing to do so, try:
def update
@user = User.find(params[:id])
if @user.update(user_params)
redirect_to "/users/#{@user.id}"
else
flash[:errors] = @user.errors.full_messages
redirect_to "/users/#{@user.id}/edit"
end
end
Upvotes: 1