除非在Rails控制器中声明?

时间:2012-08-10 17:49:08

标签: ruby-on-rails-3 controller ip limit vote

我的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投票。

任何建议都将不胜感激!

2 个答案:

答案 0 :(得分: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更改为您想要的任何时间范围。

希望这有帮助!

答案 1 :(得分:1)

投票实际上是一个单独的资源。特别是如果你想在未来实现一个更强大的系统,你会希望你的投票通过has_many关系成为一个单独的表。这样,当特定ip发生的最后一次投票(用作索引,或者用户可能是user_id的身份验证)时,可以非常容易地进行比较。此外,您还可以为IP /用户创建投票历史记录。

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