[英]Having trouble understanding some code (Ruby on Rails)
我不久前發布了一個問題,問我如何限制從Rails應用程序提交表單的速度。 一個非常耐心的用戶幫助了我,他們的解決方案效果很好。 該代碼用於我的注釋控制器,現在我發現自己想將此功能添加到另一個控制器(我的Messages控制器)中。 我立即嘗試從注釋控制器重用工作代碼,但無法正常工作。 除了要求提供工作代碼外,有人可以幫助我理解我的工作注釋控制器代碼嗎?
class CommentsController < ApplicationController
#...
before_filter :post_check
def record_post_time
cookies[:last_post_at] = Time.now.to_i
end
def last_post_time
Time.at((cookies[:last_post_at].to_i rescue 0))
end
MIN_POST_TIME = 2.minutes
def post_check
return true if (Time.now - last_post_time) > MIN_POST_TIME
flash[:warning] = "You are trying to reply too fast."
@message = Message.find(params[:message_id])
redirect_to(@message)
return false
end
#...
def create
@message = Message.find(params[:message_id])
@comment = @message.comments.build(params[:comment])
if @comment.save
record_post_time
flash[:notice] = "Replied to \"#{@message.title}\""
redirect_to(@message)
else
render :action => "new"
end
end
def update
@message = Message.find(params[:message_id])
@comment = Comment.find(params[:id])
if @comment.update_attributes(params[:comment])
record_post_time
redirect_to post_comment_url(@message, @comment)
else
render :action => "edit"
end
end
#...
end
My Messages控制器幾乎是標准的Rails生成的控制器,帶有一些前置過濾器和關聯的私有方法,用於干燥代碼並重定向不存在的頁面。
我將解釋我了解多少代碼。 創建注釋后,將創建一個具有last_post_time值的cookie。 如果他們嘗試發布另一條評論,則會檢查cookie是否是在最近兩分鍾內做出的。 如果是閃爍的警告,則不會記錄任何評論。 我真正不了解的是post_check方法的工作方式,以及如何使其適應更簡單的posts控制器。 我以為我可以重用消息控制器中的所有代碼,但以下行除外:
@message = Message.find(params[:message_id])
# (don't need the redirect code)
在post_check方法中。 我真的很想了解這一點。 有人可以解釋為什么這行不通嗎? 非常感謝您閱讀我的冗長問題。
創建和更新Messages控制器的操作:
def create
@message = Message.new(params[:message])
respond_to do |format|
if @message.save
record_post_time
flash[:notice] = "Created \"#{@message.title}\""
format.html { redirect_to(messages_url) }
else
format.html { render :action => "new" }
end
end
end
def update
respond_to do |format|
if @post.update_attributes(params[:post])
record_post_time
flash[:notice] = 'Post was successfully updated.'
format.html { redirect_to(@post) }
else
format.html { render :action => "edit" }
end
end
end
我將為MessageController類嘗試此操作,請閱讀post_check類中的注釋。 哦,我也將其作為私有方法,通常,將不可訪問的動作作為私有方法是一種最佳實踐。
class MessagesController < ApplicationController
#...
before_filter :post_check
MIN_POST_TIME = 2.minutes
def create
@message = Message.new(params[:message])
respond_to do |format|
if @message.save
record_post_time
flash[:notice] = "Created \"#{@message.title}\""
format.html { redirect_to(messages_url) }
else
format.html { render :action => "new" }
end
end
end
def update
respond_to do |format|
if @post.update_attributes(params[:post])
record_post_time
flash[:notice] = 'Post was successfully updated.'
format.html { redirect_to(@post) }
else
format.html { render :action => "edit" }
end
end
end
private
def record_post_time
# Use different cookie value than comments
cookies[:mesg_last_post_at] = Time.now.to_i
end
def last_post_time
# Use different cookie value than comments
Time.at((cookies[:mesg_last_post_at].to_i rescue 0))
end
def post_check
return true if (Time.now - last_post_time) > MIN_POST_TIME
flash[:warning] = "You are trying to reply too fast."
# What we want to do here is to redirect back to the page
# where you are before trying to create a new message or
# update an existing message.
#
# Dont use this:
# @message = Message.find(params[:id])
# redirect_to(@message)
#
# Use redirect_to :back so that you will be redirected
# to the previous page before you invoke the create or update
# action. Most likely you will be at the new action or edit
# action.
redirect_to :back
return false
end
end
希望它有助於澄清您對filter方法之前post_check的理解。
嗯,post_check應該只對create方法執行。 其他new / edit / show方法也將調用post_check並重定向。 這會導致無限循環。
before_filter :post_check, :only => [:create]
順便說一句,我認為您應該在模型中放入類似的代碼和過濾器:Fat Model-Skinny Controller。 因此,泛洪預防將始終應用於在其他控制器等中創建的注釋,而不僅僅是用戶在您的CommentsController中創建注釋時。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.