So after the user signs up, i redirect them to my additional info page where i collect some more information. However, something is wrong with my design/implementation as rails is saying im missing users/create template
this is my users controller
class UsersController < ApplicationController
def show
#user = User.find(params[:id])
end
def new
#user = User.new
end
def additional_info
#user = User.new(user_addinfo)
if #user.save
redirect_to show_path
end
end
def create
#user = User.new(user_params)
if #user.save
# UserMailer.welcome_email(#user).deliver
sign_in #user
redirect_to additional_info_path
flash[:success] = "Welcome to InYourShoes!"
#return #user
else
render'new'
end
end
private
def user_params
params.require(:user).permit(:name, :email, :password, :password_confirmation)
end
def user_addinfo
params.permit(:year)
end
end
def show is the user profile page i want to show after redirecting to the additional_info page
def additional_info is just take additional info from the private method def user_addinfo
def create is the sign up process.
After entering the basic user info, it gets redirected to additional which is fine. but after the additional, it says im missing the users/create template, but my code i attempted to redirect to show_path and #usersshow, still doesnt work
any suggestions? sorry if this seems intuitive but Im new to rails.
I think your problem is in the additional_info method, as i said in the comment. What you're doing is:
creating a user
creating a session for the user (sign_in #user) - storing somewhere the user_id in the session
redirecting to your additional_info page
And here comes the problem. As the user is already signed in you don't have any need to create a new user with additional params. You should have some helper to retrieve the current signed in user (like current_user) and in additional_info method, just update it.
So your additional_info method would become something like:
def additional_info
user = User.find session[:user_id]
user.update params[:user]
redirect_to user_path #show action
end
Related
i have a admin edit page and form in here. when i submit the form, it is going to the update action and updates the admin, there is no problem. After the update, i want redirect to the index page in the same controller. But it gets redirected to the edit form again. I tried a couple of things but in vain and gets redirected to edit page. i tried too much things but it is always going to edit page.
Controller (admins_controller.rb)
class Admin::AdminsController < ApplicationController
def index
#admins = Admin.all
end
def edit
#admin = Admin.find(params[:id])
end
def update
#admin = Admin.find(params[:id])
if #admin.update(admin_params)
redirect_back fallback_location: admin_admins_path
else
render 'edit'
end
end
private
def admin_params
params.require(:admin).permit(:id, :username, :password)
end
end
I'm trying admin_admins_path it does not work.
redirect_back like its name, it redirects to the route which it submitted the request, in this case is the edit page.
you should use redirect_to
redirect_to admin_index_path
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).
I'm building an events app with users who will each have a personal profile. I've set up a few users for the site but when I try and create and/or edit a profile for each user it refers me back to a flash message "That profile doesn't belong to you!" which is in reference to my first user profile which was set up and works fine.
I'm using Devise gem for initial set up but have built out from their with my own user controller. Here's the code from that controller -
class UsersController < ApplicationController
before_action :authenticate_user!
before_action :set_user
before_action :owned_profile, only: [:edit, :update]
def new
#user = User.new
end
def show
#user = User.find(params[:id])
end
def create
end
def edit
#user = current_user #User.find_by(params[:id])
end
def update
#user = User.find_by(params[:id])
if #user.update(user_params)
redirect_to user_path, notice: "Profile successfully updated!"
else
render 'edit'
end
end
private
def user_params
params.require(:user).
permit(:name, :username, :biography, :email, :url)
end
def owned_profile
unless current_user == #user
flash[:alert] = "That profile doesn't belong to you!"
redirect_to root_path
end
end
def set_user
#user = User.find_by(params[:id])
end
end
Any assistance would be appreciated.
I would create an admin. An easy way to do this is to add a column to your users table called admin and make it a boolean. Migrate the db.
Then check to whether a user is an admin before running the owned_profile method. In that method, change: unless current_user == #user to
unless current_user == #user || current_user.admin
Then set yourself as an admin in the console, save and then freely add profiles without that callback running.
If the issue is that Users are not able to edit their own profile, then I believe it is caused by the use of find_by within set_user:
#user = User.find_by(params[:id])
Should be:
#user = User.find(params[:id])
If you truly wanted to use find_by you could do:
#user = User.find_by_id(params[:id])
Or
#user = User.find_by(id: params[:id])
Find_by used as the 2 examples above will not throw an error if a User is not found, while find will.
Sidenote: You can remove the #user assignment within the show action.
You can do it by this way.
When user signing up, automatically creates profile. Good point of this ID of user and profile tables will be the same.
rails g model profile first_name last_name email
rails g migration add_user_id_to_profiles user_id:integer
Profile.rb
belongs_to :user
User.rb
has_one :profile, dependent: :destroy
before_create :set_profile
def set_profile
build_profile(id: self.id, user_id: self.id, email: self.email)
end
GoodLuck.
#app/controllers/sessions_controller.rb
class SessionController < ApplicationController
def new
#session = Session.new
end
def fetch
##user = User.session(params [:user])
redirect_to "http://www.google.com"
end
def create
emai = params[:email]
puts emai
user = User.find_by(:email => session[:emai])
#user = User.find_by (params [:email])
#user = User.find_by email: 'abc#xyz.com'
#user = User.find_by(params[:Email])
#if (session[:Email] = user.email)
if (user)
redirect_to "http://www.yahoo.com"
flash[:notice] = "You signed up successfully"
flash[:color]= "valid"
else
flash[:notice] = "Form is invalid"
flash[:color]= "invalid"
redirect_to "http://www.google.com"
end
#redirect_to "http://www.yahoo.com"
end
end
every time i execute my view i get redirected to google.com even though i pass the parameters.
Edit by R Peck:
My logic should send people to Yahoo if the params are set, but still sends to Google, how can I fix this?
Try:
user = User.find_by(:email => params[:sessions][:emai])
You are not getting the value of email if you only call params[:email] you should call parent first before calling the child params[:sessions][:email].
Several things wrong with your code.
Here's what I'd write:
#app/controllers/sessions_controller.rb
class SessionsController < ApplicationController
def new
#session = Session.new
end
def create
email = params[:sessions][:email]
user = User.find_by email: email
url = user ? "google" : "yahoo"
colour = user ? "valid" : "invalid"
notice = user ? "You signed up successfully" : "Your form is invalid"
redirect_to "http://#{url}.com", notice: notice, color: colour
end
private
def session_params
params.require(:session).permit(:session, :params)
end
end
OOP
I think this may be a little advanced but I'll write it anyway, for my own benefit.
Rails is object orientated (it's built on Ruby which is an OOP language). This means that each time you create/call a controller, it should be centered around objects.
A good example for you would be the Devise controllers.
This has a sessions_controller which essentially allows you to CRUD (Create Read Update Destroy) a session. This is the correct way to use a controller.
Your implementation seems to be dealing with a user, rather than a session, and as such you'd be best using a users_controller to fix it:
#app/controllers/users_controller.rb
class UsersController < ApplicationController
def new
#user = User.new
end
def create
#user = User.new
#user.save
end
end
Having said that, it does seem that you're probably going to resolve the issue to make it so that you can use the User to build a new session.
I guess it's best to remember that you have to ensure you're able to appreciate a good structure for your application
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