Post Redirect Get pattern in Rails

前端 未结 6 1298
隐瞒了意图╮
隐瞒了意图╮ 2021-01-05 15:19

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?

相关标签:
6条回答
  • 2021-01-05 15:42

    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.

    0 讨论(0)
  • 2021-01-05 15:45

    It is true, though, that you should not do redirect_to '/'. You should define root in your routes file and then do redirect_to root_path.

    Edit: Oops, that was supposed to be a comment to SpyrosP's answer.

    Also: Here is some excellence guidance on flash. Particularly this may ease your mind:

    The flash is a special part of the session which is cleared with each request. This means that values stored there will only be available in the next request, which is useful for storing error messages etc.

    The interesting things there is that, yes it is a part of the session, so answers to "use the session instead of flash" are misguided, as Justin Etheredge's answer already put it. The other thing is that it says it is useful for storing messages instead of only for storing messages. With the added "etc" it would lead me to believe that it is within the intended usage to store user information in there as well.

    One last thing, I would agree with Aditya Sanghi that you should just store the user parameters and not an entire user object in the flash.

    0 讨论(0)
  • 2021-01-05 15:47

    I didn't read the question properly.

    The validation failure you have necessitates going to a different page where a different process will occur. You tried to update a domain object, it doesn't exist. The usual response to a validation failure is to re-render the page, but you need to go to the create page.

    The flash hash seems wrong for this. I'd agree with the idea of stuffing your entered data into the session and redirecting.

    0 讨论(0)
  • 2021-01-05 15:53

    use below code

    class UsersController < ApplicationController
    
      def new
        @user = User.new(session[:user_param])
       session[:user_param]=nil
      end
    
      def create
    
        @user = User.new(params[:user])
    
        if @user.save
          # clears previously stored user if there is any
          flash.discard(:user)
          redirect_to '/'
        else
          session[:user_param] = @user
          redirect_to :action => :new
        end
    
      end
    
    end
    
    0 讨论(0)
  • 2021-01-05 15:56

    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.

    From ActionController::Base documentation

    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_store
    

    in your config/environment.rb and run rake 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
    
    0 讨论(0)
  • 2021-01-05 16:09

    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
    
    0 讨论(0)
提交回复
热议问题