2013-05-02 3 views
0

Мне нравится высушивать контроллеры, размещая код повторного ввода до и после фильтров. В моем текущем проекте, каждое действие имеет тот же respond_to блок:reply_to in after_filter

respond_to do |wants| 
    wants.html 
    wants.js { render :layout => "transition" } 
end 

Я поместил это в after_filter как так:

after_filter :respond_to_html_or_transition 

Но это приводит к этой ошибке:

Render and/or redirect were called multiple times in this action. Please note that you may only call render OR redirect, and at most once per action. Also note that neither redirect nor render terminate execution of the action, so if you want to exit an action after redirecting, you need to do something like "redirect_to(...) and return".

Это происходит даже тогда, когда в действии нет явного respond_to или redirect. Я предполагаю, что это происходит, потому что Rails (из-за отсутствия явного вызова respond_to) делает образованное предположение и создает свой собственный respond_to до after_filter. Если это так, есть ли у меня способ сохранить Rails от этого и вместо этого использовать блок в after_filter?

ответ

0

То, что вы пытаетесь выполнить, невозможно с помощью параметра after_filter. Фильтр after обрабатывает уже обработанное действие. В этот момент рендер уже завершен (либо явный, либо неявный рендер), поэтому вызов render приведет к двойному вызову.

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

Последнее, но не менее, вы можете написать ответчику пользовательских действий и заменить по умолчанию один заходящего

self.responder = CustomActionResponder 
+0

контроллер Последний вариант кажется, что лучший путь, но у меня возникают проблемы с реализацией. Переопределение метода 'to_js' с помощью' render layout: «переход» не работает. Он отображает, но он не использует макет перехода. – nullnullnull

+0

Только что он работает. 'render layout:« переход »- это хорошо. Реальная проблема исходила из того, как я назначал ответчика. Вместо того, чтобы помещать 'self.responder = CustomActionResponder' внутри контроллера (который рекомендовал и вы, и несколько блогов), я поместил' response_with (@items,: responder => CustomActionResponder) 'в конце каждого действия. Это многословие, но оно работает. Интересно, почему другой подход не работает. Я использую Rails 4; возможно, его обесценили? Или, может быть, я не делаю это правильно? – nullnullnull