I have a session controller like
def create
user = User.find_by_email(params[:session][:email])
if user && user.authenticate(params[:session][:password])
sign_in user
redirect_to user
else
flash.now[:error] = 'Invalid email/password combination' # Not quite right!
render 'new'
end
end
if you notice on successful sign in it does redirect_to user which is the show action in the User controller.
But say instead of that I have to go to the new action of user controller then how do i do that?
redirect_to user is just a shortcut for redirect_to url_for(user), which generates the url for a given resource (url_for) and then redirects to it.
If you want to redirect to another url, you can use the path helper.
redirect_to new_user_path
You could also use the url_for helper to generate an url.
redirect_to url_for(:controller => "users", :action => "new")
Which can be shortened to
redirect_to :controller => "users", :action => :new
You can even specify an url directly (redirect_to '/users/new') - which I would not recommend, as you can't change your routing later without changing all the urls.
The docs
As you can see, there are many ways to specify an url to redirect_to in rails. Take a look at the documentation for all of them
To render an action from another controller:
render 'users/new'
See: http://guides.rubyonrails.org/layouts_and_rendering.html#using-render
Related
I have just started working in rails.
I have a controller that redirects to another controller to send an email for emailid verification.
def create
#user = User.new(user_params)
respond_to do |format|
if #user.save
redirect_to :controller => 'verify', :action => 'sendmail'
else
format.html { render :new }
end
and this is the route in routes file
resources :verify
but still the program is returning an error
No route matches {:action=>"sendmail", :controller=>"verify"}
This is the code of the controller to which I am redirecting
def sendmail
# type = 1 for email and 2 for reseting password
randomNumber=rand()
verification[:value]=BCrypt::Password.create(randomNumber, :cost => 1)
verification[:type] = 1
if verification.save
Usermail.registered(#verification).deliver
end
I think Verify (singular) as a controller name won't easily be mapped by resources, instead just add a custom match
get '/verify/sendmail', to: 'verify#sendmail', as: :verification_mail
Then do
redirect_to verification_mail_path
I need to do something kind of weird in my Rails app. Once a user creates a Product instance through the create action, I need it to save and then redirect them to a Braintree payment method form if they haven't already added one to their account, and only then redirect them to the show page for the product.
Here's the product create action:
def create
#product = Product.new(product_params)
#product.set_user!(current_user)
if #product.save
if !current_user.braintree_customer_id?
redirect_to "/customer/new"
else
redirect_to view_item_path(#product.id)
end
else
flash.now[:alert] = "Woops, looks like something went wrong."
format.html {render :action => "new"}
end
end
The confirm method for the Braintree customer controller is this:
def confirm
#result = Braintree::TransparentRedirect.confirm(request.query_string)
if #result.success?
current_user.braintree_customer_id = #result.customer.id
current_user.customer_added = true
current_user.first_name = #result.customer.first_name
current_user.last_name = #result.customer.last_name
current_user.save!
redirect_to ## not sure what to put here
elsif current_user.has_payment_info?
current_user.with_braintree_data!
_set_customer_edit_tr_data
render :action => "edit"
else
_set_customer_new_tr_data
render :action => "new"
end
end
Is what I want to do possible?
You can store product id in a session variable before redirecting to braintree form, a then after complete confirmation just read this id from session and redirect to product show action.
if !current_user.braintree_customer_id?
session[:stored_product_id] = #product.id
redirect_to "/customer/new"
else
redirect_to view_item_path(#product.id)
end
Keep in mind that user can open product view page just by entering valid url address if he knows product id, so you should also handle this kind of situation. You can put before_filter in product show action to check if user has brain tree setup. If you go this way, you don't need to have condition in create action. You can always redirect to product show page and before_filter will check if user needs to update braintree data.
I am using Rails 4 and moved from CakePHP.
I have a User Model and to create a new record it uses two Actions - New and Create.
Now when i want to over ride the default for my app. i would like the users to go to Signup action to create a new user. Now when i have a Server side validation and it fails i am posting the form to lets say "create" action the user is shown in the url
'app.com/user/create' instead of 'app.com/user/signup'
Is there any way to keep the user in the same action instead of have multiple action just to display form and save the form?
# GET /users/new
def new
#user = User.new
end
# POST /users
def create
#user = User.new(user_params)
if #user.save
redirect_to #user, notice: 'User was successfully created.'
else
render :new
end
end
You should simply add a redirect in your create action when the user creation fails.
redirect_to :back, #user
I would not recommend using :back all the time but this is going to be helpful for now as by understanding the scenario you have mentioned.
By default, action new just initialize model with-or-without params. Action create save model to database. app.com/user/create is not RESTful and "Rails Way".
users_path #=> app.com/users
new_user_path #=> app.com/users/new
user_path(:id) #=> app.com/user/:id
edit_user_path(:id) #=> app.com/user/:id/edit
# and so on
In controllers you can define redirections for every action. For example:
def create
if #user.save
redirect_to user_path(#user)
else
redirect_to :back # return to previous page
end
end
More information about routing here: http://guides.rubyonrails.org/routing.html
I would stick with rails conventions but you should be able to do this if you really wanted
Routes.rb
get 'signup', to: 'users#signup'
post 'signup', to: 'users#signup'
Controller
class UsersController < ApplicationController
def signup
if request.get?
#user = User.new
elsif request.post?
#user = User.new(user_params)
if #user.save
redirect_to root_url, notice: 'Signed In'
else
#should just render signup as it's signup action
end
end
end
end
1 - My controller is this , but this not call the view whit this name is login.html.erb, im not understand beacause what happen this , is to show the form of the login.
class FinancesController < ApplicationController
# GET /finances
# GET /finances.json
def login
#user = User.find_by_name(params[:user])
if #user
session[:user_id] = #user.id
redirect_to :action => 'index'
else
redirect_to login_url
end
end
def index
#finances = Finance.all(:order => "created_at")
respond_to do |format|
format.html # index.html.erb
format.json { render json: #finances }
end
end
2 - Someone can talk to me to use the authenticate method to validate a sample login whit user and password forms some, can show to me how use this method , the find_by_name_and_password dont works.
I thanks by the answers, many.
Routes.rb
Controle::Application.routes.draw do
match 'login' => 'finances#login'
resources :finances
end
check for the #user object.
because, as of your code it will redirect to your login method if #user is not available.
To render login.html.erb from login method, there is no need for any manual redirections.
Im trying make a login page for my rails application that looks like "www.domain.com" and when you login you still are still located at the domain "www.domain.com". Is there a way that I can map 2 different actions to the same url using routes. Twitter does it this way, you log in at twitter.com and after you are logged in you are still located at twitter.com.
You can't do this by simply modifying the routes, but you can do some kind of conditional statement in your controller.
def index
if logged_in
render :action => 'show'
else
render :action => 'new'
end
end
def show
...
end
def new
...
end
There are going to be numerous ways to do this, of course.
After successful login redirect to the root URL.
routes.rb
map.resources :landings
# let's assume that, home page corresponds to landings/index
map.root :controller => "landings", :action => "index"
UserSessionsController
def create
#user_session = UserSession.new(params[:user_session])
if #user_session.save
redirect_to root_url
else
render :action => :new
end
end