Post Redirect Get pattern in Rails
I don't know how popular PRG pattern is and why one has to religiously stick to the "redirect" on failure aspect of it (actually, one good reason is sometimes you dont want to deal with the "setup" complexity at create failure and keep things dry).
What you basically need is to transfer the params for :user to new. I think @Hitesh's solution above is quite close.
class UsersController < ApplicationController
def new
if flash[:user_params]
@user = User.new(flash[:user_params])
@user.valid?
else
@user = User.new
end
end
def create
@user = User.new(params[:user])
if @user.save
# clears previously stored user if there is any
flash[:notice] = "User created."
redirect_to '/'
else
flash[:error] = "Error saving User"
flash[:user_params] = params[:user]
redirect_to :action => :new
end
end
end
Best practices for Post-Redirect-Get (PRG) with MVC in PHP
The pattern is to GET
a blank form, modify the contents of the form, then POST
that to the server, which then sends a redirect to another page which is a GET
, perhaps to a page saying Form submitted successfully.
. (Get->)Post->Redirect->Get
The first action is not really POST
. That's the end result of completing a form and submitting it. The guide is more about what to do after that POST
, as if you do not do a redirect, then the user is left on a page saying Form submitted successfully
where they could just hit F5 and do another POST
. With that redirect however, they're on that results page via a safe GET
which will not result in a double post.
As for the implementation, you should have each be its own action on the server side. This is inline with the MVC / RESTful implementation.
- GET /url?action=new -> Call new_form() method to render a new form
- POST /url?action=create -> Call create_form() method to save and redirect to /url?action=show&id=1234
- GET /url?action=show&id=1234 -> Call show_form() method to display the result
- POST /url?action=save&id=1234 -> Call save_form() method to save and redirect
You could use 3 actions here instead if you wanted to have the 2nd action call save
. Most REST/CRUD conventions use the 4, but the choice is yours. The benefits are the same as going the REST/MVC route in the first place.
See these resources as well:
- RESTful web services
- This covers typical conventions for RESTful controllers. It covers rails, but still applies to PHP as well if you're wanting to go the REST route.
How to handle a Rails redirect that starts with x pattern in the url
It should be the following in routes.rb:
get 'dashboard/*section', to: '<controllerName>#<actionName>'
Here:
- controllerName = Controller Name, e.g. Home
- actionName = Action Name, e.g. Dashboard
class HomeController
def dashboard
# inside params[:section] you'll get 'dashboard_page'
# if you're accessing '/dashboard/dashboard_page'
end
end
Reference: https://guides.rubyonrails.org/routing.html#route-globbing-and-wildcard-segments
How to redirect_to or render new action with a HTTP GET method instead of POST?
In a RESTful environment, you cannot use a POST verb to reach a "new" action on a controller. If you're confused with the routes, remember to use the command rake routes until you get used to them.
Regardless of this, I do not understand your question very well. If you want to redirect to the new action, it will always use GET, so it should be enough with:
redirect_to new_post_comment_path(@post)
Am I missing something?
Passing post data in a rails app through a redirect
When i have to do this in PHP, i store the POST data in the session, then i remove them when i'm done using them (There's even a pattern called "post / redirect / get" that tell to do this to avoid re-post of submitted data when reloading the page).
Couldn't you do what you want this way or something similar with Rails?
Rails is incorrectly sending redirect response as status 200
According to this Medium article:
Apparently there is no clean way to do ajax redirects in Rails. The
recommended way to do that is to send a regular 200 OK status code
along with some special parameter signaling the javascript side that
it is a REDIRECT.
The author suggests to make it clear with this workaround:
On the rails side, we create a helper that returns a response that has
no content but just one header x_ajax_redirect_url and status code
302.
def ajax_redirect_to(url)
head 302, x_ajax_redirect_url: url
end
A global ajax handler on the javascript side will intercept all ajax
calls across the application and redirect on seeing the appropriate
header construct.
$.ajaxSetup({
statusCode: {
302: function (response) {
var redirect_url = response.getResponseHeader('X-Ajax-Redirect-Url');
if (redirect_url != undefined) {
window.location.pathname = redirect_url;
}
}
}
});
This looks as the cleanest solution to me for now.
Is the PRG pattern incompatible with AJAX form posts?
We use Post-Redirect-Get in our app. Here's the essence of what we do, which hinges around the Request.IsAjaxRequest()
method and splitting your views into .aspx each of which host an .ascx so that each can action can be called both synchronously and asynchronously (i.e. via Ajax).
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Edit(Foo foo)
{
try
{
// Save the changes to the data store
unitOfWork.Foos.Attach(foo);
unitOfWork.Commit();
if (Request.IsAjaxRequest())
{
// The name of the view for Ajax calls will most likely be different to the normal view name
return PartialView("EditSuccessAsync");
}
else
{
return RedirectToAction("EditSuccess");
}
}
catch (Exception e)
{
if (Request.IsAjaxRequest())
{
// Here you probably want to return part of the normal Edit View
return PartialView("EditForm", foo);
}
else
{
return View(foo);
}
}
}
We have a slight variant on this as well where we specifically catch RulesException
's (from the xVal in order to treat model validation errors differently to other 'more serious' exceptions.
catch (RulesException re)
{
re.AddModelStateErrors(ModelState, "");
return View(foo);
}
Saying all that though, sometimes I get a sneaking suspicion that we might be doing it slightly wrong.
What to type in redirect_to in nested attributes in rails?
Remove :index and :show from except in your route definition then after create/update, try:
redirect_to event_event_detail_path(@event_detail)
After destroy there won't be an @event_detail to redirect_to so you probably want to:
redirect_to event_details_path
Also
rake routes | grep event
... will show you your application routes, and the Rails routing guide brings light into such dark moments
redirect_to
takes a path parameter, for instance occasions_path
to redirec to the occasions index action, or `event_event_detail_path(@event_detail) to redirect to the @event_detail show action. You can use redirect_to to tell the client (browser) to go to any part of the application laid out in your routes, or even relative or absolute URLs. Later on you will learn you can also add all kinds of parameters and HTTP status codes.
Related Topics
Upsert Multiple Records with Mongodb
Exec the Cd Command in a Ruby Script
How to Programmatically Convert Mp3 to an Itunes-Playable Aac/M4A File
How to Access Current_User Object in Model
Selenium2 Webdriver Ruby => How Click on a Hidden Link
Product Orders Between 2 Users
How to Execute 2 or More Commands in the Same Ssh Session
Why Does Hash#Select and Hash#Reject Pass a Key to a Unary Block
How to Add Conditional Rubygem Requirements to a Gem Specification
Include Erb Delimiters Inside of a String in an Erb Block
Ruby Converting Utc to User's Time Zone
How to Get Gmail Oauth or Xauth Tokens with Omniauth
What Orm to Use in One Process Multiple Db Connections Sinatra Application
Ruby: Mass Initializing Instance Variables
Rotating Letters in a String So That Each Letter Is Shifted to Another Letter by N Places
Updating from Rails 4.0 to 4.1 Gives SASS-Rails Railties Version Conflicts