Rails controller - redirect to website after create? - ruby-on-rails

I am working on a basic app that has a public facing form (for enquiries) that anyone can fill in and submit. The results are then stored for the company to do what they want with.
I have made sure that if the user is not logged in they can only access the create page, but once they submit the form, as expected, they are taken to the login page because its trying to show them the show page.
My current controller is as follows:
# POST /enquiries
# POST /enquiries.xml
def create
#enquiry = Enquiry.new(params[:enquiry])
respond_to do |format|
if #enquiry.save
format.html { redirect_to(#enquiry, :notice => 'Enquiry was successfully created.') }
format.xml { render :xml => #enquiry, :status => :created, :location => #enquiry }
else
format.html { render :action => "new" }
format.xml { render :xml => #enquiry.errors, :status => :unprocessable_entity }
end
end
end
I would imagine it's this line that needs to change:
format.html { redirect_to(#enquiry, :notice => 'Enquiry was successfully created.') }
Is it possible to do:
format.html { redirect_to(http://www.google.com) }

Yes, you can certainly redirect_to("http://any.url.com/you/want") from your controller or do whatever else you want if create is successful. Redirecting to the show action is just a common pattern.
Is this really what you want to do, though? If you redirect your user to an outside website after submitting the form, you can't give them any feedback at all about what just happened. The user might try to submit the Enquiry again, or worse, they might think something went wrong and just forget about it, lose interest, etc. I'd strongly recommend creating a "Thanks for your enquiry!" page and redirecting anonymous users there.

Related

Rails controller action redirect_to refresh page

I want my page to refresh once a record has been created, at the moment it directs it to the page before. here is the code from my controller:
def create
#license = License.new(params[:license])
respond_to do |format|
if #license.save
format.html { redirect_to :controller => 'customers', :action => 'index' }
format.json { render json: #customer, status: :created, location: #customer }
else
format.html { render action: "new" }
format.json { render json: #customer.errors, status: :unprocessable_entity }
end
end
where it says redirect_to i need that to refresh, or link to the current page, with the current id, which would be :controller => 'customers', :action => 'show' but with the id of the current page's record.
Try
redirect_to customer_path(#license.id)
instead.
Depending on what your routes.rb file says, it should work.
But if it doesn't, try:
redirect_to show_customer_path(#license.id)
However, here I have to assume that somehow, your customers_controller.rb is somehow showing records from the License model. If License and Customer are separate models, you will have to find the customer_id in some other way.
Perhaps, it is:
redirect_to customer_path(#license.customer_id)
If License is not connected to Customer in any way, you will need to pass it in as part of the post request.
Try,
I think you are passing customer_id to on params(Licensee belongs to customer), if so then
redirect_to customer_path(#license.customer) or redirect_to customer_path(params[:customer_id])

How to handle update of a single user model data separately: user info, password, extra information

I want to present users with separate pages/dialogs for editing their own information. However, the information is held in a single model (called User). Now I'm trying to find the best approach for handling the update calls from partials. My code currently:
def edit
render :layout=>!request.xhr?
end
def edit_password
render :layout=>!request.xhr?
end
def edit_extra
unless #user.extra
#user.build_extra
#user.extra.value = 2047
end
render :layout=>!request.xhr?
end
def update
respond_to do |format|
if #user.update_attributes(params[:user])
format.html { redirect_to #user, :notice => 'User was successfully updated.' }
format.json { head :no_content }
else
format.html { render :action => "edit", :layout=>!request.xhr? }
end
end
end
The thing is, all forms in methods (edit, edit_password and edit_extra) call the update method. However, there are two problems:
If the data parsing isn't validated, user is presented with the "edit" form, which is incorrect.
I want to have a password confirmation on extra data. User shouldn't be able to edit that information unless they supply a correct password.
I would like to make more generalized solution than just duplicating the update -code. The largest problem is rendering correct layout (edit, edit_password) based on the current action.
For now, I solved the problem by creating separate edit_section parameter that will be handled in update.
def update
respond_to do |format|
if #user.update_attributes(params[:user])
format.html { redirect_to #user, :notice => (t :actionsuccesful) }
format.json { head :no_content }
else
action = if params[:edit_section] then "edit_" + params[:edit_section] else "edit" end
format.html { render :action => action, :layout=>!request.xhr? }
end
end
end
And in forms (edit_password, etc)
=form_for(#user, :remote => true) do |f|
= hidden_field_tag :edit_section, "password"

Ruby on Rails revise instead of edit

I am still a bit new to RoR, and am using scaffolding to generate CRUD interfaces for data.
I am using devise for user authentication, and want to allow a user that owns a specific entry to edit or delete, but protect that data from other users. However, I would like to allow a different user to revise or create new versions.
So if a user that attempts to edit should appear as if they are editing, but when they submit, the controller should actually generate a new entry (and potentially specify the parent_id of the entry it derived from).
Any help on implementation is greatly appreciated.
Also look into Ancestry, it's a really nice library to help with versioning.
Here is my solution that I came up with. I am a ruby newb, so I assume that I can just call the create function with the same params but wasn't sure how to do that, so I just duplicated code:
def update
#section = Section.find(params[:id])
if #section.owner == current_user.id
respond_to do |format|
if #section.update_attributes(params[:section])
format.html { redirect_to(#section, :notice => 'Section was successfully updated.') }
format.xml { head :ok }
else
format.html { render :action => "edit" }
format.xml { render :xml => #section.errors, :status => :unprocessable_entity }
end
end
else
# REVISE
#childsection = Section.new(params[:section])
respond_to do |format|
if #childsection.save
format.html { redirect_to(#childsection, :notice => 'Section was successfully revised.') }
format.xml { render :xml => #childsection, :status => :created, :location => #childsection }
else
format.html { render :action => "new" }
format.xml { render :xml => #childsection.errors, :status => :unprocessable_entity }
end
end
end
end

Having problems creating a Renew action and view in Rails3

please can somebody help me with this .i want to create a renew link which will update some of the fields in a table called members,am using rails 3 and i have created my action and the corresponding view but i still have an error that states
"undefined method'renew_member_path' for #<#:0xb66bcae0>"
below is the action i created in the members_controller
Class MembersController
def renew
#member = Member.find(params[:id])
respond_to do |format|
if #member.renew_attributes(params[:member])
format.html { redirect_to(#member, :notice => 'Member was succesfully Renewed.'}
format.xml {head :ok }
else
format.html { render :action => 'renew'}
format.xml { render :xml => #member.errors, :status => :unprocessable_entity}
end
end
end
I created a view called renew.html.erb
Your route is not set. You need to update your routes.rb file to something like this:
match 'members/renew' => 'members#renew', :as => :renew_member

Redirect view after saving Rails model

When I:
self.save
or
save!
in a model it automatically redirects me to the show view for that given model. How can I override this? I want to save the model and then go to another action/view in the same controller.
In particular, I have a process where I save a members details, and then I want to continue the process by going to the next page, e.g. payment page, that uses the id of the saved model.
In your controller you might have a block like:
def create
#user = User.new(params[:place])
respond_to do |format|
if #user.save
format.html { redirect_to(#user, :notice => 'User was successfully created.') }
format.xml { render :xml => #user, :status => :created, :location => #user }
else
format.html { render :action => "new" }
format.xml { render :xml => #user.errors, :status => :unprocessable_entity }
end
end
end
You can change the target of the redirect_to (after format.html) from here - at present it is directing you to the record for that user, ie. #user. Take a look at http://api.rubyonrails.org/classes/ActionController/Base.html for a bit more info.
You likely have a block like this in your create/update methods:
respond_to do |format|
if #post.save
format.html { redirect_to(#post, :notice => 'Post was successfully created.') }
format.xml { render :xml => #post, :status => :created, :location => #post }
else
format.html { render :action => "new" }
format.xml { render :xml => #post.errors, :status => :unprocessable_entity }
end
end
So if your instance variable is named #post, and it's redirecting to the show view for the post after it saves, all you have to do is change the "redirect_to(#post, ..." part to whatever you want. Say you wanted to redirect to the root of your site - you could instead have
redirect_to(root_path, :notice => 'Post was successfully created.')
In your particular case, you could use something like this if you have your routes set up:
redirect_to(payment_page_path(#post), :notice => 'Post was successfully created.')
Hope that helps!
if you call save from your Model you will not be directed anywhere, it just does a direct model access save to the database. Your redirections are described in your controller in your create and update actions. you can find a list of routes by running rake routes and then pick the path you want your app to render when you save your model instance. you may have a route called payment_path which might look like this in your controller
map.payment :controller => :payments_controller, :action => index
and you would say in your create action
def create
if #item.save(params[:item])
redirect_to payment_path
else
flash[:error] = "there was a problem"
render :action => buy
end
end
if you need to pass a param, like user id to your route, then you need to include that in the path parameters
redirect_to payment_path(#user) #=> automagically finds the id of active record models

Resources