簡體   English   中英

無法理解某些代碼(Ruby on Rails)

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM