Лучшая практика Rails для того, чтобы иметь одну и ту же форму на нескольких страницах - PullRequest
6 голосов
/ 12 октября 2009

Я занимаюсь разработкой веб-сайта Rails 2.3.1. На всем веб-сайте мне нужна форма для создания сообщений на различных страницах (домашняя страница, страница создания сообщений, страница публикации сообщений, страница с комментариями и т. Д.) - достаточно сказать, что эта форма должна находиться на многих страницах, обслуживаемых различные контроллеры). Каждая из этих страниц отображает широкий спектр другой информации, которая извлекается в соответствующем контроллере / действии. Например, на главной странице перечислены последние 10 сообщений, содержимое, извлеченное из БД и т. Д.

Итак, я переместил форму создания поста в ее собственный раздел и включил этот раздел во все необходимые страницы. Обратите внимание, что форма в разделе Частичное POST для / вопросов (которая направляет к PostsController :: create - это поведение рельсов по умолчанию).

Проблема, с которой я сталкиваюсь, заключается в том, что форма сообщений не заполнена правильно, по умолчанию метод postsController :: create создает questions / new.html.erb метода render, даже если форма была отправлена ​​с домашней страницы (/ home /index.html.erb).

Я попытался изменить форму в частичном, чтобы отправить "submitting_controller" и "submitting_action", а в PostsController :: create, когда @ post.save? == false, я отображаю action => "../submitting_controller/submitting_action" (что немного странно, но позволяет вам отображать действия не из PostsController'а).

Это, казалось, работало нормально на поверхности. Неполная форма была отображена в представлении, которое отправило ее со всеми правильными сообщениями @ post.errors и т. Д. Проблема заключалась в том, что ВСЕ другие данные на страницах не отображались, поскольку фактические методы submiting_controller / submitting_action не были вызваны, просто связанный вид. (Помните, я сделал рендер, который сохраняет объекты экземпляра, а не redirect_to, который не сохраняет объект экземпляра @post, который имеет все сообщения об ошибках и отправленные значения.)

Насколько я вижу, у меня есть два варианта:

1) Я могу сохранить объект @post в сеансе, когда @ post.save? происходит сбой в PostsController :: create, redirect_to submitting_controller / submitting_action, после чего я вытаскиваю объект @post из сеанса и использую его для повторного заполнения формы / сообщений об ошибках. (Насколько я понимаю, хранение объектов в сеансе - ПЛОХАЯ практика в рельсах)

2) Я могу переместить всю логику, используемую для извлечения данных формы, не связанных с публикацией, из различных submitting_controller / submitting_action, поместить их в ApplicationController, создать гигантский оператор switch в PostsController :: create для submiting_controller / submitting_action и вызвать методы в ApplicationController для сбора всех дополнительных данных, необходимых для рендеринга каждой отправляющей страницы.

Мысли о том, как сделать это в Rails?

Ответы [ 2 ]

1 голос
/ 12 октября 2009

Случайно ли ваша модель Post связана с принадлежащей к каждой модели моделью, чей контроллер вы будете использовать для визуализации вашей формы? Вы выполняете какую-либо специальную обработку в контроллере Post за пределами Post.create(params[:post])?

Если вы ответили «да» на первый вопрос и «нет» на второй, вы можете обойтись с минимальными искажениями, добавив accepts_nested_attributes_for к каждому контроллеру, на котором пользователь может создать сообщение.

Несмотря на это, Робертпостилл прав в том, что, вероятно, именно тогда стоит начать смотреть на AJAX, чтобы просто заменить раздел страницы. Единственная проблема заключается в том, что делать, если у пользователя отключен JavaScript. Лично мне нравится делать дизайн для не-JavaScript сценария и добавлять удобные методы.

Что касается мыслей о том, что вы считаете своими двумя вариантами,

1) Я использовал этот метод для хранения мелкой копии объекта во флэш-хеше. Сохранение его через перенаправления. Однако это может не сработать, учитывая переменную природу сообщений. Поскольку вы можете отправлять только данные объемом около 4K, включая другую информацию в дополнение к вашей мелкой копии.

2) См. Ответ Робертпостиля

1 голос
/ 12 октября 2009

Речь идет о том, что вы переходите от полных обновлений страницы к обновлению разделов страницы с помощью AJAX. Есть несколько вещей, которые вы должны рассмотреть, но наиболее подходящим способом будет разделение ответа между ответом AJAX и простым ответом HTML. Проверьте эту статью ONLamp , эту статью регистрации или удивительную гибкую веб-разработку с книгой рельсов . По сути, ваш контроллер отображает новый div, заменяющий старый div, содержащий результат отправки частичного.

В своем вопросе вы упомянули два подхода, и поэтому я постараюсь дать вам несколько советов, почему и почему не здесь:

Вариант 1) Этот вариант не так уж и плох с парой настроек. Основной твик заключается в хранении объекта в сериализованной форме в БД. Затем просто передайте идентификатор сериализованного объекта. Ваши плюсы в том, что данные сеанса сохраняются, поэтому восстановление сеанса происходит быстрее, а ваш сеанс остается светлым. Недостатком этого является то, что наличие большого количества сессий в вашей БД приведет к загрязнению вашего приложения, и вам нужно будет подумать о том, как истечь неиспользованный сессионный перерыв с БД. Я никогда не видел этот конец хорошо ...

Вариант2) Ищите не внутри application_controller! :) Серьезно, оставь это в качестве оружия последней инстанции. Вы можете извлекать информацию из помощников и получать доступ к этим методам внутри ваших контроллеров и представлений. Однако тестирование этого материала не так просто, поэтому будьте осторожны, прежде чем выбрать этот маршрут. Операторы Switch могут быть заменены в OO-приложениях с небольшим размышлением, конечно, в его случае вы можете использовать опциональные хэши, чтобы получить надежный способ получить некоторое представление о состоянии приложения во время выполнения запроса.

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