I have a rails app with a page for a user to edit their own profile
app/views/manage_users/edit.html.erb and app/views/manage_users/new.html.erb contain:
<%= render 'form' %>
app/views/manage_users/_formt.html.erb contains:
<%= form_for(#user, :as => :user, :url => {:action => #form_action, :id => #user.id}) do |f| %>
When I fire up the page http://localhost:3000/manage_users/2/edit it shows me a typical form to edit a user object's data. If i blank out the email address http://snag.gy/atnmV.jpg and submit the form, I get an error that I would expect http://snag.gy/NRfwn.jpg and the url is now http://localhost:3000/manage_users/2:
Started PUT "/manage_users/2" for 127.0.0.1 at 2014-01-25 21:01:45 -0600
Processing by ManageUsersController#update as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"B44/1b5m8usyAfe0hzLHNyjk/7Fpn5iEu3u6wGJMGL0=", "user"=>{"user_details_attributes"=>{"first_name"=>"Jeff", "last_name"=>"Smith", "id"=>"2"}, "email"=>"", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]"}, "button"=>"", "id"=>"2"}
If i put the email address back in and submit the form, the url now points to http://localhost:3000/manage_users?id=2 and I get the error No route matches [PUT] "/manage_users"
Why is it doing this and how can I fix it. If i just go to the initial page to edit a user and save it right away (instead of blanking out the email), everything works just fine.
app/controllers/manage_users_controller.rb
class ManageUsersController < ApplicationController
before_filter :admin_only, :except => [:edit, :update]
# GET /manage_users
# GET /manage_users.json
def index
#users = User.active
respond_to do |format|
format.html # index.html.erb
format.json { render json: #users }
end
end
# GET /manage_users/new
# GET /manage_users/new.json
def new
#user = User.new
#user.build_user_details
#form_action = 'create'
respond_to do |format|
format.html # new.html.erb
format.json { render json: #user }
end
end
# GET /manage_users/1/edit
def edit
#user = User.find(params[:id])
#permissions_disabled = params[:id].to_i == current_user.id.to_i
#p #permissions_disabled
able_to_edit_profile?
session[:return_to] ||= request.referer
#form_action = 'update'
end
# POST /manage_users
# POST /manage_users.json
def create
#user = User.new(params[:user])
#p "in create"
respond_to do |format|
if #user.save
format.html {
flash[:notice] = 'User was successfully created.'
redirect_to(:action => :index)
}
format.json { render json: #user, status: :created, location: #user }
else
format.html { render action: "new", notice: 'Error creating user.' }
format.json { render json: #user, status: :unprocessable_entity }
end
end
end
# PUT /manage_users/1
def update
#user = User.find(params[:id])
able_to_edit_profile?
# required for settings form to submit when password is left blank
if params[:user][:password].blank?
params[:user].delete("password")
params[:user].delete("password_confirmation")
end
respond_to do |format|
if #user.update_attributes(params[:user])
#user.save
# sign the user in with their new password so it doesn't redirect to the login screen
if current_user == #user
sign_in #user, :bypass => true
end
format.html {
p "in success format.html"
flash[:notice] = 'User was successfully updated.'
redirect_to session.delete(:return_to)
}
else
p "in else"
format.html { render action: "edit", notice: 'Error updating user.' }
#format.html {
#flash[:notice] = #user.errors
# redirect_to edit_manage_user_path(#user)
#}
end
end
end
private
# If the user is not an admin and trying to edit someone else's profile, redirect them
def able_to_edit_profile?
if !current_user.try(:admin?) && current_user.id != #user.id
flash[:alert] = "That area is for administrators only."
redirect_to :root
end
end
end
EDIT
So by changing this:
format.html { render action: "edit", notice: 'Error updating user.' }
to:
format.html {
flash[:notice] = #user.errors.full_messages.to_sentence
redirect_to edit_manage_user_path(#user)
}
I'm able to circumvent the issue. I'm still curious as to why rendering 'edit' doesn't work after a failed update.
When you render the edit action from the update method (in the failure path), it doesn't run the edit method, so #form_action is nil when you render the form. You'll need to address that.
I usually don't need to set the url, only in rare cases do I. You may be able to leave that out and let rails take care of the url and HTTP method.
Related
My problem is that when I want to render the new action after an error in the create action, it's render without the styles for that action.
This are the new action and create action from the same controller:
# GET /users/new
def new
#user = User.new
render layout: 'application'
respond_to do |format|
format.html{}
end
end
# POST /users
# POST /users.json
def create
#user = User.new(user_params)
#role = Role.new
#role.email = #user.email
#role.tipo = "user"
respond_to do |format|
if #role.save
#Not relevant
else
format.html { render :new }
format.json { render json: {:estado => "false"}, status: :unprocessable_entity }
end
end
end
One thing that I detected is that when I submit the form from the new action and it has and error, then the url is /users. Shouldn't it be /users/new?
That the URL is /users is standard in the rails framework. That is the POST #create route which includes the error_messages.
The problem is this part in your 'new' action:
render layout: 'application'
A solution can be to add into your 'create' action:
render :new, :layout => 'application'
instead of just render :new.
So, use this instead:
format.html { render :new, :layout => 'application' }
It will render your layouts/application.
Hello i have the titled error when i go to http://localhost:3000/users/new
fill out the form to create user and click the button "create user"
My table consists of first_name, last_name, email, and password
I tried to fix if for half an hour. Can anyone help? Thanks
class UsersController < ApplicationController
def index
#users = User.order(:email)
respond_to do |format|
format.html # index.html.erb
format.json { render json: #users }
end
end
# GET /users/1
# GET /users/1.json
def show
end
# GET /users/new
def new
#user = User.new
end
# GET /users/1/edit
def edit
end
# POST /users
# POST /users.json
def create
#user = User.new(user_params)
respond_to do |format|
if #user.save
format.html { redirect_to users_url, notice: 'User #{#user.email} was successfully created.' }
format.json { render :created, location: #user }
else
format.html { render :new }
format.json { render json: #user.errors, status: :unprocessable_entity }
end
end
end
You might have included a presence validation in you Model file
validates :name, presence :true
when it doesnt really exist as column
You probably have something like:
<%= f.text_field :name %>
in your form. It's incorrect, since you don't have name column in users table, instead, you have first_name and last_name columns.
I have the following code:
def edit
#post = Post.find(params[:id])
if !current_user.posts.include?(#post)
permission_denied
end
respond_to do |format|
format.html # edit.html.erb
format.json { render :json => #post }
end
end
def permission_denied
flash[:notice] = 'Sorry, you are not authorized to access that page.'
redirect_to root_url
end
How could adapt this code, so it doesn't show me the "Render and/or redirect were called multiple times in this action" . I have tried adding "and return" to redirect_to root_url and return, but I keep getting the same error.
You should return from the edit action:
def edit
#post = Post.find(params[:id])
return permission_denied if !current_user.posts.include?(#post)
respond_to do |format|
format.html # edit.html.erb
format.json { render :json => #post }
end
end
I have this method:
def update
#user = User.find(params[:id])
respond_to do |format|
if #user.update_attributes(params[:user])
if params[:mypmnode]
session[:return_to] = projects_pmnode_path(params[:mypmnode])
sign_in(#user)
end
format.html { redirect_to(session[:return_to], :notice => 'User was successfully updated.') }
format.xml { head :ok }
else
#create_company = true if params[:user][:company_id].blank? and params[:user][:company_attributes].length > 0
#create_department = true if params[:user][:department_id].blank? and params[:user][:department_attributes].length > 0
format.html { render :action => "edit" }
format.xml { render :xml => #user.errors, :status => :unprocessable_entity }
end
end
end
The idea is that if the user is updated, He is automatically signed-in and redirected to a page where authentication is required.
In this page, I have: before_filter :authenticate_user!
This doesn't work on redirect.
If I then go to another page making use of this sign_in function, then the user logs-in correctly.
Any idea why redirect doesn't work? Thx!
UPDATE:
to make it clearer, I insert the second page code (controller):
class PmnodesController < Projects::BaseController
before_filter authenticate_user!
def index
#pmnodes = Pmnode.all
respond_to do |format|
format.html
end
end
If the password is updated on #user, devise will invalidate the session. After the update_attributes, you could try calling sign_out first.
sign_out(#user)
sign_in(#user)
Are you sure that your progam goes inside this blog
if params[:mypmnode]
session[:return_to] = projects_pmnode_path(params[:mypmnode])
sign_in(#user)
end
if not this should sign in your use automatically.
def update
#user = User.find(params[:id])
respond_to do |format|
if #user.update_attributes(params[:user])
if params[:mypmnode]
session[:return_to] = projects_pmnode_path(params[:mypmnode])
end
sign_in(#user)
format.html { redirect_to(session[:return_to], :notice => 'User was successfully updated.') }
format.xml { head :ok }
else
#create_company = true if params[:user][:company_id].blank? and params[:user][:company_attributes].length > 0
#create_department = true if params[:user][:department_id].blank? and params[:user][:department_attributes].length > 0
format.html { render :action => "edit" }
format.xml { render :xml => #user.errors, :status => :unprocessable_entity }
end
end
end
I had a similar problem:
I had a controller method that created and signed in a user
def new
#user = User.create!
sign_in #user
redirect_to some_nondefault_path
end
where some_nondefault_path required authentication. The new action did not require authentication. The user was getting created and signed in, but the user session wasn't persisting and the user was getting 401-unauthorized and redirected to the signin page instead of some_nondefault_path.
I ended up solving it by adding
skip_before_filter :verify_authenticity_token, :only => :new
to the first controller. It seemed to be trying to verify the CSRF token before creating the user session, which was failing and blocking the creation of a normal user session (even though it wasn't trying to authenticate_user!).
Hope this helps!
I have an option for a user to update their username in their profile. However, when the url for their profile has been set as localhost/user/username and when they submit their changes, they are redirected to their old username (not the new updated one).
Here is my update from users_controller.rb
Any suggestions?
def update
#user = User.find_by_username(params[:id])
#page_title = "Edit Profile"
respond_to do |format|
if #user.update_attributes(params[:user])
format.html { redirect_to(user_url,
:notice => "Your profile has been saved.") }
format.xml { head :ok }
else
format.html { render :action => "edit" }
format.xml { render :xml => #user.errors,
:status => :unprocessable_entity }
end
end
end
also, I'm using
def to_param
username
end
Doesn't user_url take #user as an argument? How have you defined your route for that?
One thing I can think of immediately is #user.reload!.