#ruby-on-rails #render
#ruby-on-rails #рендеринг
Вопрос:
Привет, в моем приложении у меня такая ситуация:
у some_controller.rb
i есть код для этого:
def start
method1(param)
....
if some_case
render json: {ok: "ok"}
end
end
def method1
...
if some_case
render json: {error: "Some error"}
return
end
end
Дело в том, что когда приходит время отображать json с ошибкой, я получаю double render
ошибку. Он советует мне использовать render .. and return
. Я пробовал даже это, и все равно получаю эту ошибку.
Это потому, что render
do не прерывает само выполнение, а просто возвращает что-то вызывающему методу? Если это так, что я могу сделать в моем случае? Дело в том, что method1
на самом деле это большой метод, и я, конечно, хочу, чтобы он был отделен от start
метода. И в случае, если нет причин для вывода ошибки там, я хочу, чтобы выполнение start
было продолжено.
Спасибо!
Комментарии:
1. Ваш
return
применяется только к методу, в котором он находится (method1
) . Затем управление возвращаетсяstart
и продолжается с остальной частью кода. Включая второй рендеринг. Вы можете использовать фильтр before, как предложил MikDiet.2. @SergioTulentsev Итак, я об этом подумал. Здесь
return
работает как обычноreturn
на других языках и не означает остановки дальнейшего выполнения. Спасибо!
Ответ №1:
Рассмотрите возможность использования filter вместо этого. Это работает:
before_action :method1, only: :start
def start
....
if some_case
render json: {ok: "ok"}
end
end
def method1
...
if some_case
render json: {error: "Some error"}
return
end
end
Когда рендеринг происходит в filter, он не запускает само действие, поэтому двойной рендеринг не происходит.
Комментарии:
1. Да, это звучит как решение. Не знаю, почему я не подумал о фильтрах. И просто для того, чтобы стать умнее: как я мог бы столкнуться с такой же ситуацией, если мне нужно позвонить
method1
в серединеstart
? Возвращает 0 (или что-то подобное) или сообщение об ошибкеmethod1
и обрабатывает этот ответstart
?2. @Ngoral: в этом случае лучше всего извлечь рендеринг из
method1
, чтобы он только выполнял… что бы он ни делал сейчас, кроме рендеринга 🙂 Вы можете заставить его возвращать логическое значение. Если он возвращает true, родительский метод продолжается. Если он возвращает false, родительский метод выдает ошибку и останавливается3. @SergioTulentsev Итак, как я и ожидал. Еще раз спасибо =)
Ответ №2:
Используйте этот код
def method1
if some_case
render json: {error: "Some error", status: :unprocessable_entity }
end
end
Комментарии:
1. Как это предотвратит проблему двойного рендеринга?