Я не понимаю код для избежания DoubleRenderError - PullRequest
4 голосов
/ 28 сентября 2011

Официальная страница имеет этот фрагмент:

def show
  @book = Book.find(params[:id])
  if @book.special?
    render :action => "special_show" and return
  end
  render :action => "regular_show"
end

Почему это не эквивалент?

def show
  @book = Book.find(params[:id])
  if @book.special?
    render :action => "special_show"
    return
  end
  render :action => "regular_show"
end

Или, почему это не используется?

 def show
   @book = Book.find(params[:id])
   if @book.special?
     render :action => "special_show" and return
   else
     render :action => "regular_show"
   end
 end

Я не понимаю необходимости render ... and return

Ответы [ 3 ]

2 голосов
/ 29 сентября 2011

Это действительно плохой пример. Я действительно против метода and return короткого замыкания, потому что многие люди не понимают, что это значит, и, кроме того, его можно упустить из виду, если вы не будете внимательно следить.

Лучший подход заключается в том, что вы описываете, где у вас есть явное выражение if, которое разделяет две возможности. Я бы пошел еще дальше, чтобы свернуть все это в один render вызов с заранее определенным аргументом действия:

def show
  @book = Book.find(params[:id])

  # Determine the template to be used for this action
  render_action = @book.special? ? 'special_show' : 'regular_show'

  # Render the appropriate template
  render(:action => render_action)

rescue ActiveRecord::RecordNotFound
  render(:action => 'not_found', :status => :not_found)
end

В примере также отсутствует ловушка для вызова find, которая может вызвать исключение, если запись не найдена. Это обычное упущение, и я уверен, что большинство людей об этом полностью забывают. Помните, что вы не должны отображать 500 «серверных ошибок» в хорошо разработанном приложении даже при получении неверных запросов.

Самый простой способ избежать двойной ошибки рендеринга - это, в конце концов, только один вызов render.

1 голос
/ 29 сентября 2011

В первом фрагменте, если and return отсутствовал, а @book.special? был правдив, вы бы получили DoubleRenderError. Это потому, что оба вызова render будут выполнены.

Имея это в виду, все фрагменты эквивалентны в том смысле, что они предотвратят повторный вызов render. Кроме того, в последнем фрагменте and return не требуется, поскольку только один из render будет вызываться.

1 голос
/ 29 сентября 2011

Они на самом деле все эквивалентны.Ваш пример как раз оказался с наименее интуитивно понятной версией.Не уверен, почему, но этот стиль часто встречается в примерах на Rails.

По сути, and - логический оператор с очень низким приоритетом связывания, поэтому строка типа expression_a and expression_b приведет к expression_a оценивается, а затем, если он не оценивается как nil или false, он будет оценивать expression_b.Поскольку render возвращает ... ну, что-то не ложно - точно не знаю, что ... ваш пример ведет себя точно так же, как render whatever; return (или с разрывом строки вместо точки с запятой, как во втором фрагменте).

Лично я предпочитаю третий фрагмент с блоком if / else (которому не нужен and return, потому что он все равно находится в конце функции).В твоем лице очевидно, что он делает, и мне нравится это в моем коде.

Надеюсь, это поможет!

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