How can I implement PRG in Rails?
I used PRG in Rails, but I am not totally convinced it's right. I was wondering is there any better way to handle it 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
                        Use the session, Luke
The way you implemented it in your blog post is quite fine, however you may want to use session instead of flash to store your @user and optionally use the ActiveRecord session store to keep cookies from getting bloated.
ActiveRecord::SessionStore - Sessions are stored in your database, which works better than PStore with multiple app servers and, unlike CookieStore, hides your session contents from the user. To use ActiveRecord::SessionStore, set
config.action_controller.session_store = :active_record_storein your
config/environment.rband runrake db:sessions:create.
So you should…
class UsersController < ApplicationController
  def new
    @user = session[:user] || User.new
  end
  def create
    @user = User.new(params[:user])
    if @user.save
      # clears previously stored user if there is any
      session[:user] = nil
      redirect_to '/'
    else
      session[:user] = @user
      redirect_to :action => :new
    end
  end
end
                        I'm no expert in these matters, but this looks good. From what I understand flash is a part of the session. So the answers telling you to switch to session seem a bit misguided. In this case you want the data to be cleared after the redirect. Other than shoving it in the session, I'm not sure where you would put it.
As far as your cookie size increasing, well, the default session provider for Rails is a cookie in Rails 3. You could swap the session provider out if you wanted to keep the data server side. It is encrypted though, so you are probably okay with the data in the cookie, unless size is an issue.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With