How to route to a belongs_to object - ruby-on-rails

I have a controller method that creates a user. I want it to route to user preferences when the user creates himself. How do I write the path? Here's the method:
def create
#user = User.new(params[:user])
if #user.save
redirect_to profiles_path, :notice => "Signed up!"
else
render "new"
end
end

I'd assume that when the users creates himself you want it to redirect to an edit option of this users preferences. Now, if the users is not created, there cant be any preferences to it. So im thinking that, once the users saves, you should create a record in the 'preferences' model, with the user_id so you know where to redirect to. (This is assuming that the #preferences model has a user_id field).
Something like:
if #user.save
#preferences.new
#preferences.user_id = #user.id
#preferences.save
redirect_to edit_preferences_path(:user_id=> #user.id), :notice => "Signed up!"
else
whatever
end
Hope it helps.

Related

Rails controller redirect to form in another controller then back to saved model

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.

Rails Actions for Form Posting

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

Ruby on Rails - Creating a profile when user is created

So basically I have wrote my own authentication instead of using a gem so I have access to the controllers. My user creation works fine but when my users are created I want to also create a profile record for them in my profile model. I have got it mostly working I just cant seem to pass the ID from the new user into the the new profile.user_id. Here is my code for the user creation in my user model.
def create
#user = User.new(user_params)
if #user.save
#profile = Profile.create
profile.user_id = #user.id
redirect_to root_url, :notice => "You have succesfully signed up!"
else
render "new"
end
The profile is creating it is just not adding a user_id from the newly created user. If anyone could help it would be appreciated.
You should really do this as a callback in the user model:
User
after_create :build_profile
def build_profile
Profile.create(user: self) # Associations must be defined correctly for this syntax, avoids using ID's directly.
end
end
This will now always create a profile for a newly created user.
Your controller then gets simplified to:
def create
#user = User.new(user_params)
if #user.save
redirect_to root_url, :notice => "You have succesfully signed up!"
else
render "new"
end
end
This is now much easier in Rails 4.
You only need to add the following line to your user model:
after_create :create_profile
And watch how rails automagically creates a profile for the user.
You have two errors here:
#profile = Profile.create
profile.user_id = #user.id
The second line should be:
#profile.user_id = #user.id
The first line creates the profile and your are not 're-saving' after the assignment of the user_id.
Change these lines to this:
#profile = Profile.create(user_id: #user.id)

Form redirects after create in Rails

I am following the tutorial on railstutorial.org but with modifications. There is a form where I want to create users. But when i create users, it redirects me to the user page. How can I edit it? I want it to remain on the same page with a flash notification stating that the person has already been created. Below is the create function I currently have.
def create
#user = User.new(params[:user])
if #user.save
flash.now[:success] = "User Added!"
render 'new'
else
render 'new'
end
end
Try:
redirect_to new_user_path, notice: 'New User Added'
Or check your routes, and see which page you want to redirect, in console type:
rake routes
Hmm..try redirect_to users_path, notice: 'User Added'

Rails: attributes not being saved even though I called #user.save

I'm running this function, and I KNOW that it gets called because the redirect_to is working. But for some reason, #user isn't! If it helps, #user is devise based.
def make_feed_preference
#user = current_user
##user.feed_preference = params[:preference]
#user.feed_preference = "time"
#user.name = "Shoo Nabarrr"
#user.karma = 666
#user.save
redirect_to '/posts'
end
I fixed it myself. I had to create a new class attached to users in order to get it to work. Lol.
Do you have any validations on this user? They are probably blocking this save. The redirect_to will be called regardless of whether or not the save passes or fails.
I would recommend doing it like this instead:
if #user.save
redirect_to '/posts'
else
render :feed_preference
end
Where :feed_preference is the form where users enter their feed preferences.
There are cases where I want to be sure to update a flag or other field on a record even if the record has validation problems. (However, I would never do that with unvalidated user input.) You can do that thusly:
def make_feed_preference
case params[:preference]
when 'time', 'trending_value', 'followers'
current_user.update_attribute 'feed_preference', params[:preference]
flash[:notice] = 'Your feed preference has been updated.'
else
flash[:notice] = 'Unknown feed preference.'
end
redirect_to '/posts'
end

Resources