undefined method `update_attributes' - ruby-on-rails

I have look around and I'm not sure how to fix this problem. I have a undefined method `update_attributes'. I'm thinking it's because #user is not defined. So if I am able to define #user it should be able to fix it. The thing is I don't know how to define #user in order to fix it. If someone could point me in the right direction that would be great.
Users.controller.rb:
def edit
#user = User.find(params[:id])
end
def update
#user.update_attributes(params[:id])
flash[:success] = "Account updated"
sign_in #user
redirect_to #user
else
render 'edit'
end

If you are using restful paths for your resources then update action should be something like this:
def update
#user = User.find(params[:id])
if #user.update_attributes(params[:user])
flash[:success] = "Account updated"
sign_in #user
redirect_to #user
else
render 'edit'
end
end
We essentially first find the user record through the params[:id] and then update the user fields.

Related

What does redirecting to an instance mean in Ruby on Rails

What does redirecting to a particular instance mean? I am aware of how the redirecting works.
class UsersController < ApplicationController
def show
#user = User.find(params[:id])
end
def new
#user = User.new
end
def create
#user = User.new(user_params)
if #user.save
log_in #user
flash[:success] = "Welcome to the Sample App!"
redirect_to #user
else
render 'new'
end
end
def edit
#user = User.find(params[:id])
end
private
def user_params
params.require(:user).permit(:name, :email, :password,
:password_confirmation)
end
end
I understand the following ways of redirecting:
redirect_to :new (redirect to new method and displaying the new.html.erb file)
redirect_to "show" (redirect to show.html.erb file or the path for show method)
but what does redirect_to #user mean? Which method and path are we are redirecting to?
If you check the redirect_to documentation, you will find this.
Record - The URL will be generated by calling url_for with the options, which will reference a named URL for that record.
It's Rails "magic" for redirecting to the #show action for that #user using GET. You'll find similar things in default Rails forms as well, but for actions like POST.
According to section 7.4.1 from Michael Hartl's The Rails Tutorial:
redirect_to #user
can be written instead of
redirect_to user_url(#user)
Quoting Michael Hartl:
This is because Rails automatically infers from redirect_to #user that
we want to redirect to user_url(#user).

Updating a record via a action method

User signs up, is redirected to a page to be collected info, pretty straight forward
I for my life can't figure out how to do this
My controller for the user
def show
#user = User.find(params[:id])
end
def new
#user = User.new
end
def additional_info
#user = User.find session[:user_id]
#user = User.update(user_addinfo)
redirect_to user_path
end
def create
#user = User.new(user_params)
if #user.save
#session[:user_id] = #user.id
#UserMailer.welcome_email(#user).deliver
sign_in #user
redirect_to additional_info_path
flash[:success] = "Welcome to InYourShoes!"
else
render'new'
end
end
private
def user_params
params.require(:user).permit(:name, :email, :password, :password_confirmation)
end
def user_addinfo
params.require(:user).permit(:year)
end
end
user_addinfo is the action method that i want to call updating my record on for my additional_info method.
the def create method has commented line that i'm unsure if necessary, particularly the session[:user_id] = #user.id. I was told that i need this in order to keep track of my session, but perhaps someone can debunk this for me, as im following michael hartl's tutorial.
as of right now with this code, rails is giving me a parameter missing in the
params.require(:user).permit(:year) line.
Much help is greatly appreciated. Ive been trying many different things, and cant seem to figure this out
Change your controller code as below:
def additional_info
#user = User.find params[:id] ## Set #user
end
def update
if #user.update(user_addinfo)
redirect_to user_path(#user), notice: 'User was successfully updated.'
else
render action: 'additional_info'
end
end
def create
#user = User.new(user_params)
if #user.save
#session[:user_id] = #user.id
#UserMailer.welcome_email(#user).deliver
sign_in #user
redirect_to additional_info_path(#user) ## Pass #user
flash[:success] = "Welcome to InYourShoes!"
else
render'new'
end
end
and in your routes.rb update the additional_info route as
get 'info/:id' => 'users#additional_info', :as => 'additional_info'
You additional_info action seems to be wrong. You need to pass in the id of the user for whom you are collecting additional information.
def additional_info
#user = User.find params[:id]
#user.update_attributes(user_addinfo)
redirect_to user_path(#user)
end
The line you have commented in your create method:
#session[:user_id] = #user.id
Is what is storing the user id to a session variable and not a param in the url.
You then have this line commented in your additional_info method
#user = User.find session[:user_id]
This is looking up the user by the id that you would have previously stored in the session variable.
At that point the user object would be stored in user
If you need it in your instance variable, make sure to modify the line to be
#user = User.find session[:user_id]
Your user would then be stored in #user and be able to be accessed in the view

ArgumentError in UsersController#update

I have not changed my users_controller file, but now I am receiving this error after updating user profile "wrong number of arguments (2 for 1)". It points to "app/controllers/users_controller.rb:41:in `update'".
My code looks to be right but I have to be missing something. Any ideas?
users_controller:
class UsersController < ApplicationController
def new
#user = User.new
end
def profile
#profile = User.profile
end
def create
#user = User.new(params[:user])
if #user.save
UserMailer.registration_confirmation(#user).deliver
session[:user_id] = #user.id
redirect_to root_url, notice: "Thank you for signing up!"
else
render "new"
end
end
def show
#user = User.find(params[:id])
end
def edit
#user = User.find(params[:id])
end
def index
#users = User.all
end
def destroy
User.find(params[:id]).destroy
flash[:success] = "User deleted."
redirect_to users_url
end
def update
#user = if current_user.role?(:admin)
User.find(params[:id])
else
current_user
end
if #user.update_attributes(params[:user])
flash[:success] = "Account updated"
redirect_to #user
else
render 'edit'
end
end
end
I found the fix for what I was having troubles with.
In user.rb I had to add:
def has_role?(role_name)
role.present? && role.to_sym == role_name.to_sym
end
and then in the controller I just added:
#user = if current_user.has_role?(:admin)
Before it was missing the ".has" part to it.

using redirect and if multiple times

My question is actually fairly simple, how do I make a create action which checks if a user is logged in, and if she/he is then redirect to the dashboard instead of rendering the index page where they've got links and stuff to go to and sign up. Also why is the code below not working.
class UsersController < ApplicationController
def new
#user = User.new
end
def create
if current_user.nil?
redirect_to dplace_index_path
if current_user
#user = User.new(params[:user])
if #user.save
auto_login(#user)
redirect_to dplace_index_path
end
end
end
end
end
Your code isn't doing what you expect because the if statements are actually nested (you want elsif with this same structure -- or see my suggested fix below). Here's what your code, when properly formatted, actually looks like:
def create
if current_user.nil?
redirect_to dplace_index_path
if current_user
#user = User.new(params[:user])
if #user.save
auto_login(#user)
redirect_to dplace_index_path
end
end
end
end
Logically, you will never get down into the second if statement, because current_user must be nil to enter the first. Try something like this instead:
def create
if current_user
#user = User.new(params[:user])
if #user.save
auto_login(#user)
redirect_to dplace_index_path
end
else
redirect_to dplace_index_path
end
end
I rearranged the code, but it should logically do what you want now. I put the "happy path" first (the current_user exists), and moved the redirect into the else statement.
General user authentication:
def create
user = User.find_by_email(params[:email])
if user && user.authenticate(params[:password])
session[:user_id] = user.id
redirect_to dashboard_url, :notice => "Logged in!"
else
flash.now.alert = "Invalid email or password"
render "new"
end
end
Try:
def create
if current_user.blank? # .blank? will check both blank and nil
# logic when user is not logged in
redirect_to index_path
else
# logic when user is logged in
redirect_to dashboard_path
end
end
def create
redirect_to dplace_index_path unless current_user
# no need to check current_user again
#user = User.new(params[:user])
if #user.save
auto_login(#user)
redirect_to dplace_index_path
end
end

Rails - Controller error

just getting a really weird error and was wondering if anyone could enlighten me as to what is going on.
First of all here is my code:
class UsersController < ApplicationController
def index
list
render("list")
end#end index
def new
#user = User.new
end#end new
def create
#user = User.new(params[:user])
if #page.save
flash[:notice] = "Page Created Successfully!"
redirect_to(:action => 'list')
else
render('new')
end#if else
end#end create
def list
#list = User.order('users.position ASC')
end#end list
def show
#user = User.find(params[:id])
end#end show
def edit
#user = User.find(params[:id])
end#end edit
def update
#user = User.find(params[:id])
if #user.update_attributes(params[:page])
flash[:notice] = "Page updated Successfully"
redirect_to(:action => 'show', :id => #user.id)
else
render('edit')
end#end if else
end#end update
def delete
#user = User.find(params[:id])
end#end delete
def destroy
User.find(params[:id]).destroy
flash[:notice] = "User has been removed"
redirect_to(:action => 'list')
end#end destroy
end#end class
I am getting a type error when I run the server and go to http://localhost:3000/users/new
NameError in UsersController#new
uninitialized constant UsersController::User
Rails.root: C://Documents/Programming/Ruby Files/kccoding
Application Trace | Framework Trace | Full Trace
app/controllers/users_controller.rb:7:in 'new'
But I don't see myself trying to do that at all... AND I am getting no line numbers as to where this error is coming from... Any suggestions?
Kelan
EDIT ~~~ I changed the variables to User.<>, but I'm getting an "uninitialized constant UsersController::User" error. It is in whichever method I am trying to call.
I think this is your problem:
render('new')
It should be:
render :action => 'new'
Try that in your new method.
You sure it's not User.new that you want.
def new
#user = User.new
end#end new
Instead of Users.new you need to type:
def new
#user = User.new
end#end new
Check for proper model name everywhere in controller (Users => User)
It seems error doesn't just come from controller code.
Do post you error trace from log files, something can be found from that only.

Resources