Возникают проблемы с пониманием некоторого кода (Ruby on Rails) - PullRequest
0 голосов
/ 15 мая 2010

Я недавно опубликовал вопрос , спрашивающий, как я могу ограничить скорость, с которой форма может быть отправлена ​​из приложения на рельсы. Мне помог очень терпеливый пользователь, и их решение прекрасно работает. Код был для моего контроллера комментариев, и теперь я хочу добавить эту функцию в другой контроллер, мой контроллер сообщений. Я сразу же попытался повторно использовать рабочий код из контроллера комментариев, но не смог заставить его работать. Вместо того, чтобы просить рабочий код, может кто-нибудь помочь мне понять мой рабочий код контроллера комментариев?

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, с несколькими фильтрами до и связанными частными методами для СУШКИ кода и перенаправления для несуществующих страниц.

Я объясню, какой объем кода я понимаю. При создании комментария создается файл cookie со значением last_post_time. Если они пытаются опубликовать другой комментарий, cookie проверяется, был ли последний из них создан за последние две минуты. Если это было флэш-предупреждение, отображается и комментарий не записывается. На самом деле я не понимаю, как работает метод post_check и как я могу адаптировать его для моего более простого контроллера записей. Я думал, что смогу повторно использовать весь код в контроллере сообщений, за исключением строки:

@message = Message.find(params[:message_id])
# (don't need the redirect code)

в методе post_check. Я очень хочу это понять. Может кто-нибудь объяснить, почему это не работает? Я очень ценю, что вы читаете мой длинный вопрос.

Создание и обновление действий контроллера сообщений:

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

Ответы [ 2 ]

1 голос
/ 15 мая 2010

Хм, post_check должен выполняться только для метода create.В противном случае новые методы / edit / show также будут вызывать post_check и перенаправлять.Это приводит к бесконечному циклу.

before_filter :post_check, :only => [:create]

Кстати, я думаю, вы должны поместить в модель код и фильтры, подобные этому: Fat Model - Skinny Controller.Таким образом, предотвращение флуда будет всегда применяться к комментариям, созданным в других контроллерах и т. Д., А не только тогда, когда пользователи создают их внутри вашего CommentsController.

1 голос
/ 15 мая 2010

Я попробую это для класса 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

Надеюсь, это поможет прояснить ваше понимание того, что делает post_check перед фильтром.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...