redirect_to не работает для приложений RESTful? - PullRequest
2 голосов
/ 22 декабря 2009

Как давний пользователь Ruby и Rails, мне до сих пор не удавалось по-настоящему задуматься о шаблоне get-and-redirect в Rails. Типичным примером этого является вызов действия create (), а затем перенаправление пользователя на действие show () для отображения вновь созданного элемента:

class JournalEntries

  def index
    @entries = JournalEntry.all
  end

  def create
    @entry = JournalEntry.new( :name => "to-do list" )
    @entry.save
    redirect_to :action => "index"
  end
end

Однако, это имеет свойственный недостаток, заключающийся в том, что вы удваиваете свой сетевой трафик. Это как замедляет работу сайта ваших пользователей, так и увеличивает плату за пропускную способность.

Так почему бы просто не сделать это вместо этого:

  def create
    @entry = JournalEntry.new( :name => "to-do list" )
    @entry.save
    index

Тот же вывод, и никаких дополнительных затрат не требуется. Но в дополнение к этому есть еще более существенная проблема: redirect_to может перенаправлять только с помощью GET. Это вызывает серьезные проблемы для приложений RESTful, которые используют четыре различных метода HTTP.

В моем случае я хотел, чтобы пользователь мог вызывать / journals / 8 и получать журнал с этим идентификатором. Если он не был найден, я хотел создать новый пустой объект Journal. В любом случае объект Journal затем будет отправлен вызывающей стороне.

Обратите внимание, что метод create () в RESTful Rails маршрутизируется из "POST / Players". Но поскольку redirect_to (и основной HTTP-редирект) может отправлять только запросы GET, он фактически перенаправляет в «GET / Players», который является методом index (). Такое поведение явно неверно.

Единственное решение, которое я мог придумать, это просто вызвать create () вместо redirect_to (), как в моем примере выше. Вроде нормально работает.

Есть мысли о том, почему redirect_to предпочтительнее прямого вызова действий?

Ответы [ 3 ]

2 голосов
/ 22 декабря 2009

Если они обновляют страницу, они не раздражают: «Отправить данные?» всплывающее окно

Дело не только в том, что всплывающее окно раздражает (и не имеет смысла для большинства пользователей) - если пользователь нажимает «да, заново выполнить POST», он в конечном итоге создает другую запись в журнале (или что-то еще).

Кроме того, раздражает, что URL-адрес читает /posts/create вместо /posts, поскольку пользователь не может скопировать / повторно использовать его.

2 голосов
/ 22 декабря 2009

Причина этого, как вы указываете. Вы перенаправляете на запрос GET, который является правильным, когда дело доходит до REST (только обновления с POST / PUT, только получение данных с GET).

Перенаправление, безусловно, дает небольшие издержки при перенаправлении, но поскольку между браузером и сервером фактически не передаются никакие данные, за исключением данных POST и перенаправления (которое только отправляет новый URL-адрес в браузер), я надеваю Не думаю, что проблема с Bandwith вызывает беспокойство.

Но с другой стороны, вы не должны перенаправлять в / журналы (позвонив redirect_to :index), вы должны перенаправить его на вновь созданную запись в журнале (позвонив redirect_to @entry), которая будет работать, если вы правильно настроили маршруты например, map.resources :journals

Обновление:

Я думаю, что для создания Журнала, когда его нет, вы должны попросить пользователя больше информации. Какова причина для вас, чтобы создать запись? У записи должен быть какой-то текст или какой-то другой ввод от пользователя, поэтому я думаю, что с точки зрения REST (и рельсов) вы должны фактически перенаправить ее на метод new() (с запросом GET), где пользователь может ввести дополнительную информацию. , затем он отправит вход, создаст запись и после перенаправления на вновь созданную запись.

Если у вас нет какой-либо дополнительной информации, которую нужно вставить, я не уверен, как это сделать RESTful, но я бы, вероятно, сделал это, поместив логику создания в отдельный метод, который я будет вызывать из create() и show() метод, а затем просто продолжать с show(), вообще не перенаправляя, но и не вызывая метод ресурса.

0 голосов
/ 22 декабря 2009

Я человек из Python / Django, но причины перенаправления не зависят от языка:

  1. Если они обновляют страницу, они не раздражают: «Отправить данные?» всплывающее окно.
  2. Это дает вам полностью чистый, RESTful URL для страницы, которую они просматривают. Если вы использовали POST, это может не иметь особого значения, но если для обновления использовался GET, то вам определенно нужно избавиться от любых висящих параметров.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...