Post Redirect Get Pattern in Rails

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



Leave a reply



Submit