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
Related
When i use scaffold in rails , controller creates various methods like
new,create,show,index etc
but here i can't understand transition of new action to create action
eg. when i click on new Post it look up for new action,now it render _form,but when at time of submit how data entered to that particular table, where the create action of controller called and how ?
My posts_controller is as
def new
#post = Post.new
#post.user_id = current_user.id
#post.save
respond_to do |format|
format.html # new.html.erb
format.json { render json: #post }
end
end
# GET /posts/1/edit
def edit
#post = Post.find(params[:id])
authorize! :manage, #post
end
# POST /posts
# POST /posts.json
def create
#post = Post.new(params[:post])
respond_to do |format|
if #post.save
format.html { redirect_to #post, notice: 'Post was successfully created.' }
format.json { render json: #post, status: :created, location: #post }
else
format.html { render action: "new" }
format.json { render json: #post.errors, status: :unprocessable_entity }
end
end
end
By default scaffolding on form (read here)
When the user clicks the Create Post button on this form, the browser
will send information back to the create action of the controller
(Rails knows to call the create action because the form is sent with
an HTTP POST request; that’s one of the conventions that were
mentioned earlier):
def create
#post = Post.new(params[:post])
respond_to do |format|
if #post.save
format.html { redirect_to(#post,
:notice => 'Post was successfully created.') }
format.json { render :json => #post,
:status => :created, :location => #post }
else
format.html { render :action => "new" }
format.json { render :json => #post.errors,
:status => :unprocessable_entity }
end
end
end
If you want customize an action on new form scaffold, you should add :url => {:action => "YourActionName"} on your form.
Example :
#form
form_for #post, :url => {:action => "YourActionName"}
#controller
def YourActionName
#post = Post.new(params[:post])
respond_to do |format|
if #post.save
format.html { redirect_to(#post,
:notice => 'Post was successfully created.') }
format.json { render :json => #post,
:status => :created, :location => #post }
else
format.html { render :action => "new" }
format.json { render :json => #post.errors,
:status => :unprocessable_entity }
end
end
end
#route
match '/posts/YourActionName`, 'controllers#YourActionName', :via => :post
It's all about HTTP verbs and routes.
Your form will make a POST request to the /posts route. If you list your routes using rake routes, you'll see that all POST requests to that specific route are being directed to the create action in PostsController, or posts#create for short.
When you point your browser to /posts/new, it renders the new action, which presents you with a form to fill out (defined in app/views/posts/new.html.erb and app/views/posts/_form.html.erb. When you click the Submit button in your form, it posts your data to the create action, which actually creates the record in the database.
Looking at your PostsController code, you probably don't want to have the line
#post.save
in your new action, since that will save a blank record to the database - whether the user completes the form or not. And, you'll probably want to move
#post.user_id = current_user.id
to your create action, since that is where you're actually saving the post to the database.
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])
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
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
I'm diving into RoR and as I'm going through the tutorials, scaffolds, and docs, I'm coming across some code that confuses me. For example, I just read up on the 'redirect_to' method, but the guide I read didn't cover the example of redirecting to an instance var, such as the code that is generated in a typical scaffold...
# POST /articles
# POST /articles.xml
def create
#article = Article.new(params[:article])
respond_to do |format|
if #article.save
format.html { redirect_to(#article, :notice => 'Article was successfully created.') }
format.xml { render :xml => #article, :status => :created, :location => #article }
else
format.html { render :action => "new" }
format.xml { render :xml => #article.errors, :status => :unprocessable_entity }
end
end
end
In the statement format.html { redirect_to(#article, :notice => 'Article was successfully created.') }, the code is redirecting to the instance var article, which causes a 'redirect_to' the show method in the current controller. Why does this cause it to redirect to the show method?
Thanks so much for your help!
Why does this cause it to redirect to the show method?
Because if you don't specify particular action, Rails assumes you want to 'show' object. If you have another action in mind, try
redirect_to :action => :do_something, :id => #article