【问题标题】:Restrict a visitor submit the form if it was already submitted by him如果访问者已经提交了表单,则限制访问者提交表单
【发布时间】:2017-05-08 06:23:39
【问题描述】:

我想限制访问者多次提交表单,而我认为唯一的方法是使用 cookie。在我的控制器中,我创建了一个 cookie:

class RatingsController < ApplicationController
  require 'securerandom'
  before_action :session_cookie

  def create
    @rating = Rating.new(rating_params)
    @rating.save
    render json: { rating: @rating.casino.average_rating.to_f.round(2) }, status: 200
  end

  private

  def rating_params
    params.require(:rating).permit(:score, :casino_id)
  end

  def session_cookie
    cookies[:name] = { value: SecureRandom.base64, expires: Time.now + 3600}
  end

end

我正在使用的表单 - 通过单击星号提交(这是 5 星评级,我使用 ajax 提交)。现在,如何使用该 cookie 限制访问者再次提交表单?第一个想法是向db添加一列并在那里保存一个cookie,然后使用验证来检查cookie的唯一性,但我不知道这是否是个好主意。

【问题讨论】:

    标签: jquery ruby-on-rails ajax cookies


    【解决方案1】:

    使用 cookie 进行此类验证的问题在于,如果用户真的想再次投票,他可以重置计算机上的 cookie,或者即使您的用户在一周前投票但不记得了他投票了,他在另一个浏览器上看不到他的投票。

    所以假设你有用户,我的意思是他们已经登录并且你可以访问用户,你可以创建一个名为 usersVote 的新模型,这样你就可以存储用户 id、casino_id 和分数,这将是一些东西像这样。

    class CreateUsersVote < ActiveRecord::Migration
        def up
            create_table :users_vote do |t|
                t.integer 'score', null:false
                t.references :user, null:false
                t.references :casino, null:false
            end
        end
    
        def down
            drop_table :users_vote
        end
    end
    

    因此,如果用户从他所在的任何计算机再次提交,您将负责处理。

    编辑:因此,如果没有用户验证该用户的唯一方法是使用您所说的 cookie,但您不需要让 rails 或数据库参与此任务,因为如果您将无法验证任何内容用户像我上面所说的那样更改他的 cookie,所以你这样做的方式只是使用 jquery:

    $.cookie("userHasVoted", 1, { expires : 10 });
    //10 is the number of days when the cookie will expire
    

    您可以将其放在您的 ajax 提交中,如果用户再次提交,您将阻止他提交:

    if($.cookie("userHasVoted") == 1) {
        alert("You have submited already");
        //prevent user from submiting
    }
    

    【讨论】:

    • 该应用没有可以登录的用户。
    【解决方案2】:

    一种方法是在 ratings 表上添加布尔列 submitted

    迁移

    add_column :ratings, :submitted, :boolean, :default => false
    

    运行bundle exec rake db:migrate

    然后在您的Rating 模型中

    class Rating < ActiveRecord::Base
    
        def submitted!
            self.submitted = true
            self.save
        end
    
    end
    

    然后,在您的 AJAX 控制器操作中,您可以执行类似的操作

    class RatingsController < ApplicationController
    
      def create
        @rating = Rating.new(rating_params)
        if @rating.save
            @rating.submitted!
            render json: { rating: @rating.casino.average_rating.to_f.round(2), submitted: true }, status: 200
        else
            render json: { errors: @rating.errors }, status: 422
        end
      end
    
    end
    

    然后在你的 AJAX 成功块上,你可以

    success: function(res, status, xhr) {
        if (res.submitted == true) {
            // hide or disable the button on your UI with jQuery/JS
        }
    }
    

    这样,表单提交不仅会针对该 AJAX 调用进行持久化,还会保留在您的数据库中。 下次用户访问此页面重新提交时,您可以从数据库中提取用户的评分并检查submitted 标志,如果用户已经提交或不使用它在您的视图文件中添加if 块隐藏按钮。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-06-11
      • 1970-01-01
      • 1970-01-01
      • 2014-04-10
      • 2012-10-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多