2010-05-14 2 views
0

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

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 

Мои сообщения контроллер довольно много стандартные рельсы генерируются контроллер с несколькими фильтрами, прежде чем и связанными с ними частными методами высыхания и кода перенаправления для не страниц существующих.

Я объясню, сколько кода я понимаю. Когда создается комментарий, создается файл 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 
+0

Что означает «это срабатывает на« record_post_time »в создании действия/метода? – jdl

+0

Я получаю сообщение об ошибке «неопределенная локальная переменная или метод« record_post_time ». извините за неясность. Я отредактирую свой вопрос. – BasicObject

+0

Упс, у меня была опечатка в моем коде. Больше нет ошибки record_post_time. Я просто не знаю, что заменить «@message = Message.find (params [: message_id]) « с, и вы хотите понять код. Извините за эту путаницу. Я соответствующим образом отредактировал свой вопрос. Теперь я просто получаю сообщение об ошибке: «Не удалось найти сообщение без идентификатора» при попытке сделать сообщение. Он говорит, что проблема заключается в методе post_check. – BasicObject

ответ

1

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

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

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

+0

Я думаю, что это было необходимо! Спасибо! – BasicObject

1

Я попытаюсь это для класса 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 перед методом фильтра.

+0

Благодарим вас за помощь. Ваши комментарии были действительно полезны. Я попробовал ваш код, а в firefox ошибка: «Эта проблема иногда может быть вызвана отключением или отказом принимать файлы cookie». Я попробовал это снова после удаления файла cookie, такого же результата. Поэтому я думаю, что это бесконечный цикл перенаправления. Есть идеи? – BasicObject

+0

, объединив как ваш ответ, так и Рагмаанир, я достиг решения. Большое спасибо! – BasicObject

Смежные вопросы