1

我的 Rails 3 应用程序控制器中有以下代码:

  def like
    @suggestion = Suggestion.find(params[:id])
    @suggestion.voteip = request.env['REMOTE_ADDR']
    @suggestion.update_attribute(:votes, @suggestion.votes + 1)
    redirect_to suggestions_url
  end

  def dislike
    @suggestion = Suggestion.find(params[:id])
    @suggestion.voteip = request.env['REMOTE_ADDR']
    @suggestion.update_attribute(:votes, @suggestion.votes - 1)
    redirect_to suggestions_url
  end

如您所见,代码将投票整数递增/递减 1,并将用户 IP 地址添加到名为voteip.

我想要实现的是一个简单的阻止来自同一 IP 的投票连续两次。因此,例如,如果我的 IP 是123.123.123.123并且我对某事进行了投票,那么我就不能从同一个 IP 地址再次对相同的建议(向上或向下)投票。

这是一种非常简单且远非万无一失的限速投票方法。虽然,在将要使用的环境中,它几乎是完美的!

一旦我完成了这项工作,我计划为投票时间戳添加另一列,然后我可以做一些事情,比如只允许在 5 分钟后从同一个 IP 投票。

任何意见,将不胜感激!

4

2 回答 2

1

一种方法是找到具有REMOTE_ADDR ip 的最后一票。

将此添加到您的控制器中。

def like
  @suggestion = Suggestion.find(params[:id])
  remote_addr = request.env['REMOTE_ADDR']

  @last_vote = Suggestion.find_ip(remote_addr).last

  if @last_vote.created_at < 2.minutes.ago
    render :text => "get lost"
  else
    @suggestion.voteip = remote_addr
    @suggestion.update_attribute(:votes, @suggestion.votes + 1)
    redirect_to suggestions_url
  end
end

并将其添加到您的建议模型中

def self.find_ip(ip)
  where('voteip = ?', "#{ip}")
end

我创建了一个快速应用程序并对其进行了测试,因此它确实可以工作。当然,您可以将其更改为2.minutes.ago您想要的任何时间范围。

希望这可以帮助!

于 2012-08-10T20:28:33.737 回答
1

投票实际上是一个单独的资源。特别是如果你想在未来实现一个更强大的系统,你会希望你的投票是一个单独的表,通过 has_many 关系。通过这种方式,可以非常容易地比较特定 ip 的最后一次投票发生的时间(用作索引,或者用户是否通过了 user_id 的身份验证)。这也允许您为 IP/用户创建投票历史。

用户/ip 有很多建议,有很多投票。只是我的两分钱。

于 2012-08-11T02:19:04.287 回答