Rails: Prevent duplicate inserts due to pressing back button and save again

前端 未结 8 1316
难免孤独
难免孤独 2020-12-09 12:13

Think about a simple Rails scaffold application with a \"new\" action containing a form to add records to a database with a \"save\" button. After the \"create\" action the

相关标签:
8条回答
  • 2020-12-09 12:59

    After some investigations I found a suitable solution based on cookies. Here it is:

    In the controller's "new" action, a timestamp with the current time is generated and rendered in the form as hidden field. When the user submits the form, this timestamps gets back to the controller's "create" action. After creating the record, this timestamp is stored in the session cookie. If the user goes back to the "new" form via browser's back button, he gets a stale form, which means its timestamp is older than the one stored in the cookie. This is checked before creating the record and results in an error message.

    Here is the controller code:

    def new
      @post = Post.new
      @stale_form_check_timestamp = Time.now.to_i
    end
    
    def create
      @post = Post.new(params[:post])
    
      if session[:last_created_at].to_i > params[:timestamp].to_i
        flash[:error] = 'This form is stale!'
        render 'new'
      else
        @post.save!
        @stale_form_check_timestamp = Time.now.to_i
        session[:last_created_at] = @stale_form_check_timestamp
      end
    end
    

    And here the form code:

    - form_for @post do |f|
      = tag :input, :type => 'hidden', :name => 'timestamp', :value => @stale_form_check_timestamp
      = f.input :some_field
      = .......
    
    0 讨论(0)
  • 2020-12-09 13:05

    You can use validators to make sure that no duplicate values are inserted. In this case validates_uniqueness_of :field

    If you for example want to prevent users from having the same email address you could put the following code in your user model.

    validates_uniqueness_of :email
    

    This checks the column for any previous entries that are the same as the one your trying to inert. Good luck

    0 讨论(0)
提交回复
热议问题