2010-09-04 4 views
20

У меня есть следующий фрагмент кодаКак остановить контроллер рельсов?

def show 
    unless logged_in? 
     login_required 
     return 
    end 
    #some additional code 
    #that should only execute 
    #if user is logged in 
end 

Это прекрасно работает. Теперь я хочу переместить регистрацию в фильтр перед фильтром. Проблема в том, что когда я возвращаюсь из метода вне шоу, это не останавливает выполнение шоу ... как я могу остановить show от прохождения с помощью кода из внешнего метода (т. Е. Того, который можно было бы назвать от перед фильтра)?

Спасибо!

ответ

16

Если вы вернете false из файла before_filter, выполнение запроса немедленно прекратится.

Если вы просто заставляете свой метод login_required возвращать false (или перенаправлять), если они не вошли в систему, и заставить его возвращать true, если они есть, то просто before_filter :login_required, он должен работать отлично.

Edit: Как Lenry говорится ниже, это не будет работать в Rails 2.0.1+ Вместо того, чтобы прекратить использование запроса head :ok в коде

+0

работал отлично. Спасибо! –

+0

Актуально. Проверьте ответ от Ленни ниже. – tdgs

17

В Рельсы версии 2.0.1 и выше, вы должны перенаправить или отправить ответ, чтобы остановить выполнение действия.

От Agile Web Development with Rails Errata:

# 45840: неправильно:.

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

A before_filter не прекращает обрабатывать цепочку фильтров on on return false больше.

Из выпуска нот Rails 2.0.1: * Изменен before_filter остановки произойдет автоматически при рендере или перенаправлять, но уже не на простое возвращение ложным [David Heinemeier Хансон]

--Rob Christie

redirect_to, render и head все остановятся. Например, head :ok ответит на запрос только кодом ответа OK OK, и действие не будет выполнено.

+6

Если вызов 'render' находится внутри цепочки фильтров, вызов' render' * не будет * останавливать выполнение действия контроллера. (http://guides.rubyonrails.org/layouts_and_rendering.html#avoiding-double-render-errors) – pje

+3

Если рендер останавливает выполнение, почему вы получаете двойную визуализацию при рендеринге дважды? – Mohamad

+4

Важным отличием здесь является то, что 3 метода необходимо вызывать из 'before_filter', чтобы остановить выполнение. – maletor

1

Чтобы остановить обратный вызов цепочки в Rails 5 вы можете использовать

throw :abort 
+3

Я не понимаю, где лучшее место, чтобы «поймать» этот брошенный символ.Если я хочу ввести некоторую логику, общую для всех контроллеров, которая предотвращает дальнейшую обработку, и я бросаю ': abort' в' ApplicationController', где я его поймаю? – sameers

+0

thow: abort предназначен только для проверки модели, а не для контроллеров. – bkunzi01

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