Как сохранить (или обновить) объект без формы

Я реализовал стандартный процесс Rails (и RESTful) для CRUD объекта.

Единственная настройка (или «конфигурация по соглашению»), которая мне нужна, заключается в следующем:

После стандартной формы редактирования, вместо показа объекта, я показываю его "предварительный просмотр" (это просто действие "показать" с некоторыми корректировки в представлении и с помощью «object.status = preview»), в этот момент мне нужно разрешить пользователю «подтверждать» или «сохранять» этот предварительно просмотренный объект с помощью простой кнопки. Например, если пользователь снова отправляет форму редактирования (или тот же объект), но без необходимости видеть его снова. Просто нажмите кнопку «Подтвердить».

(В действии обновления я проверяю, является ли object.status «предварительным просмотром», и если это так, я считаю его подтвержденным и показываю подтверждающее сообщение вместо предварительного просмотра).

Единственное, чего мне не хватает, — это кнопка «Подтвердить» в представлении «показать», чтобы ВСТАВИТЬ @object.

Как я могу это реализовать?

PS: я знаю, что лучше всего показывать предварительный просмотр в режиме редактирования (как и на stackoverflow.com), но в моем приложении дизайн очень важен, поэтому мне нужно предоставить максимально приближенный к реальности предварительный просмотр.


person Darme    schedule 25.10.2011    source источник
comment
Мне интересно, единственное ли решение состоит в том, чтобы настроить скрытую форму для отправки с помощью кнопки подтверждения. Но я думаю, что гипотетический способ сообщить Rails (3.1) напрямую отправить [PUT] переменную экземпляра [@object] будет более элегантный. Так вот вопрос: существует ли он?   -  person Darme    schedule 25.10.2011
comment
Есть много возможных способов справиться с этим, например, хранить объекты в отдельной таблице до тех пор, пока они не будут подтверждены, и обрезать устаревшие правки, но скрытая форма выполняет свою работу и не имеет состояния, что более соответствует соглашениям HTTP. Я упоминал, что это намного проще?   -  person coreyward    schedule 25.10.2011
comment
Вы почти убедили меня .. Вы должны опубликовать это как свой ответ, чтобы его можно было принять и / или проголосовать.   -  person Darme    schedule 25.10.2011
comment
Я сделал. Я поделился потоком и некоторым кодом для него.   -  person coreyward    schedule 25.10.2011


Ответы (2)


Вам, вероятно, не нужно другое действие, просто еще одно представление. В основном поток примерно такой:

  1. Пользователь попадает на страницу редактирования. Форма визуализируется. Они редактируют его и отправляют…
  2. Вызывается действие Update. Параметр «предварительный просмотр» недоступен, поэтому представление «предварительный просмотр» отображается вместо фактического сохранения формы.
  3. Предварительный просмотр показывает предварительный просмотр (например, show), но также имеет копию формы со скрытыми полями (через CSS) и дополнительным скрытым значением, называемым «предварительный просмотр» со значением «1».
  4. Когда пользователь нажимает «Подтвердить», форма отправляется обратно в действие обновления, которое затем видит параметр «предварительный просмотр», фактически сохраняет объект и перенаправляет на страницу показа.

Вот код контроллера, так как это самая сложная часть:

# controller
def show
  @widget = Widget.new
end

def edit
  @widget = Widget.find(params[:id])
end

def update
  previewed = params.delete(:previewed)

  @widget = Widget.find(params[:id])
  @widget.attributes = params

  if @widget.valid? && previewed
    @widget.save!
    redirect_to widget_path(@widget), :notice => 'Yay'
  elsif @widget.valid?
    render :preview
  else
    render :edit
  end
end
person coreyward    schedule 25.10.2011
comment
Я знаю, что мне не нужно другое действие, то, что вы назвали предварительным параметром для меня, - это object.status (мне нравится сохранять в базе данных, если последний статус объекта - предварительный просмотр). В основном мне было интересно, есть ли способ избежать скрытой формы, поскольку в предварительном просмотре (представление показа) у меня есть переменная экземпляра @object, готовая к PUT... Как вы думаете, можно ли сказать Rails 3.1 сделать тот? - person Darme; 25.10.2011
comment
A) Если у вас есть 2 статуса, вы должны вместо этого использовать логическое значение. Оно либо есть, либо его нет. Б) Объекты не помещаются. PUT — это глагол действия HTTP (и на самом деле этого даже не происходит, он имитируется через POST и параметр с именем _method со значением PUT). Если вы имеете в виду, что ваш объект готов к сохранению, да, и его можно так же легко подготовить для повторного сохранения. Это не требует больших ресурсов, и вам категорически не следует пытаться сохранять состояние на стороне сервера, так как это противоречит соглашениям HTTP. Вы, конечно, можете усложнить это, если хотите, но я не вижу необходимости. - person coreyward; 25.10.2011
comment
Да, если бы у меня было только 2 статуса, я использовал логическое значение, но мне нужно отслеживать 5 различных возможных статусов (доступно, куплено, предварительно просмотрено, в ожидании, одобрено), и я не вижу другого возможного решения, кроме как хранить его в БД. Пожалуйста, простите мое упрямство, но я пытаюсь сделать это правильно и раз и навсегда :-). Итак, вы заявляете, что в представлении с доступной переменной @object лучший способ сообщить Rails об обновлении — это создать скрытую форму. Нет ли способа напрямую вызвать действие обновления (с помощью button_to или чего-то еще), передав объект в качестве параметра без скрытой формы? - person Darme; 25.10.2011
comment
На самом деле, я попробовал ваше решение, и оно оказалось проще, чем я ожидал: я просто вызвал ‹%= render 'form' %› в представлении «show», а затем сделал отображение полей: none с помощью css. Хорошо, ты меня понял. - person Darme; 25.10.2011
comment
Ха-ха-ха, я рад, что вы попробовали и нашли, что это сработало для вас. - person coreyward; 25.10.2011

Я думаю, вам нужно будет изменить действие создания, чтобы отобразить Presenter, который вы можете создать для отображения своих данных. Просто используйте стандартный класс Ruby и настройте его для представления данных, которые вы хотите подтвердить, и добавьте настраиваемый маршрут, чтобы URL-адрес предварительного просмотра/подтверждения помещался в ресурс. Вы можете столкнуться с проблемами, если у вас есть стандартное соглашение resources :object. Я думаю, вы захотите настроить показ, редактирование, удаление маршрутов сами по себе, чтобы иметь возможность контролировать новый/создавать маршрут.

Если вы никогда не использовали презентатор или не знакомы с ним, в Интернете есть несколько хороших ресурсов. Не стесняйтесь читать сообщения Стива Клабника на тему здесь и здесь.

person Caley Woods    schedule 25.10.2011
comment
Что, если я переключу, на основе object.status, PUT прямо в представлении шоу? Как мне сказать Rails, чтобы PUT @object без скрытой формы? Является ли это возможным? - person Darme; 25.10.2011