【发布时间】:2011-10-09 22:13:06
【问题描述】:
我希望访问者只能对每个链接投票一次。我了解,如果他们清除 cookie,他们将能够再次投票。我将如何在 Rails 中实现此功能?我在下面附上了我的文件。谢谢
【问题讨论】:
标签: ruby-on-rails ruby ruby-on-rails-3 cookies
我希望访问者只能对每个链接投票一次。我了解,如果他们清除 cookie,他们将能够再次投票。我将如何在 Rails 中实现此功能?我在下面附上了我的文件。谢谢
【问题讨论】:
标签: ruby-on-rails ruby ruby-on-rails-3 cookies
我不会将其存储在 cookie 甚至会话中。您应该在包含user_id 和link_id 的votes 表中跟踪这些。
每次用户投票时,检查此表中的记录,如果存在则抛出错误。如果不存在,则在此表中插入一条记录并增加链接表上的投票计数,可能使用计数器缓存。
【讨论】:
我不建议这样做,但如果你坚持我会说你应该创建一个哈希,其中链接的 id 作为键,并且它们的值根据投票类型设置为 true 或 false。
我会这样改变你的控制器:
def up
@link = Link.find(params[:id])
session[:voting] ||= {}
unless session[:voting][@link.id]
if session[:voting][@link.id].nil?
points = 1
else
points = 2
@link.update_attribute :points, @link.points + points
session[:voting][@link.id] = true
end
redirect_to :action => :index
end
def down
@link = Link.find(params[:id])
session[:voting] ||= {}
unless session[:voting][@link.id] == false
if session[:voting][@link.id]
points = 2
else
points = 1
@link.update_attribute :points, @link.points - points
session[:voting][@link.id] = false
end
redirect_to :action => :index
end
这个逻辑应该属于模型,但我们不应该访问模型内部的会话变量。您可以在模型中重构此代码,然后将会话从控制器传递给它。应该是这样的:
def vote type, session
return if session[:voting][id] == type
added_points = session[:voting][id].nil? ? 1 : 2
update_attribute :points, points + (type ? added_points: -added_points)
session[:voting][id] = type
end
在此处了解有关会话的更多信息: http://guides.rubyonrails.org/action_controller_overview.html#session
希望有效。
【讨论】: