В качестве предыстории я нахожусь на ранних стадиях разработки большого проекта RoR для компании, в которой я работаю, и мы планируем придерживаться Rails в течение следующих 5-10 лет.На данный момент мы находимся в проекте, где пытаемся получить полезные практики и настроить фреймворк, чтобы он работал в соответствии с нашими потребностями.Мы рассмотрели все плюсы и минусы создания полноценного веб-приложения (стиль Backbone.js) по сравнению со статическим ограниченным приложением Rails на основе JS.Хотя мы хотели бы использовать веб-приложение, я решил, что использование Backbone.js приведет к:
- Полному дублированию представлений и маршрутов (проблема обслуживания в долгосрочной перспективе)
- Сложность отслеживания полиморфных ассоциаций и их маршрутов
- Не позволили бы нам использовать помощники вида на стороне клиента (проблема обслуживания)
- Дублирование некоторой информации о модели
- Медленные компьютеры на стороне клиента (вне нашего контроля), которые будут испытывать трудности при его запуске
Чтобы попытаться уменьшить это, мы решили пойти на более гибридный подход, но настойчивобольше логики на стороне сервера, при этом поддерживая архитектуру RESTFUL как API как можно лучше.Мы планируем, чтобы начальные загрузки страницы выполнялись в обычном режиме с использованием Rails, а затем любые манипуляции на странице отправляют запрос через AJAX и получают обратно объект JSON, который содержит отрендеренную частичную часть и некоторую дополнительную информацию (например, флэш-обновления, JSON).представление объекта, дополнительные JS включает, если необходимо, и т. д.)
Проблема, с которой мы сталкиваемся, заключается в том, что, насколько я понимаю, мы не можем поддерживать архитектуру RESTFUL и иметь несколько партиалов / представлений для одних и тех же данных.,Как пример этого, если бы я хотел запросить список заказов с сервера через заказы / индексы, он вернул бы только одно представление данных.Если бы у меня была расширенная таблица, список или какой-то другой вид / частичный / виджет, для которого я хотел, чтобы запрошенное частичное было использовано.
Для этого я добавил параметр [: частичный] (которая является либо надстройкой на маршруте, либо параметром url), которая предоставляет серверу как запрашиваемую информацию, так и представление, которое я ожидаю получить. Это будет работать само по себеОднако я также хотел бы, чтобы с сервера одновременно отправлялась дополнительная информация (например, флэш-обновления, представление данных в формате JSON и т. д.).В идеале мы хотим, чтобы это было гибким, быстрым и передавалось с сервера в формате JSON.
С этой целью я переписал существующий JSON-ответчик следующим образом, и вы можете заметить, что мой взломпришлось использовать для отображения шаблонов HAML / ERB внутри JSON:
module ExtraFunctions
def partial_options
params.include?(:partial) ? { :partial => params[:partial] } : {}
end
def flash_options
{ :file => 'layouts/_flash.html.haml' }
end
end
ApplicationController.send :include, ExtraFunctions
#I would love to be using the ERB templating and views
#instead of this kludge. But this will have to do.
ActionController::Renderers.add :json do |json, options|
#Change the format so we can render the html templates
self.formats = [:html]
options = { :layout => false }
partial_opt = options.merge(self.respond_to?(:partial_options) ? self.partial_options : {})
flash_opt = options.merge(self.respond_to?(:flash_options) ? self.flash_options : {})
obj = {
json: json.as_json,
partial: render_to_string(partial_opt),
flash: flash,
flash_partial: render_to_string(flash_opt),
user: @current_user
#js-includes: #Working on this
}
#Change the format back
self.formats = [:json]
json = obj.to_json(options) unless obj.kind_of?(String)
json = "#{options[:callback]}(#{json})" unless options[:callback].blank?
self.content_type ||= Mime::JSON
json
end
Вы заметите, что там есть место для js-includes, причина в том, что я хочувозможность динамически включать в конце игры с помощью head.js.Это было бы для более простого управления зависимостями, поскольку начальное представление не будет включать в себя некоторые из частичек, которые запрашиваются через AJAX (т. Е. Если я взял форму для ввода нового адреса, и эта форма имеет некоторую проверку AJAX, как включенав верхней части, используя тег content_for).В идеале, мне бы очень хотелось, чтобы это был JSON-макет, который будет выглядеть примерно так (хотя я надеюсь, что с синтаксисом, более покрытым сахаром):
** json/application.json.erb **
{
json: <%= json.as_json %>,
partial: <%= render_to_string(partial_opt) %>,
flash: <%= flash %>,
flash_partial: <%= render_to_string(flash_opt) %>,
user: <%= @current_user =>,
js-includes: <%= yield :js_includes %>,
<%= yield =>
}
Я работал над этими соображениями /проблемы на некоторое время, и у меня два вопроса:
1) Есть ли что-то вопиюще глупое в том, что мы делаем?Есть ли лучшее или более стандартное решение?
2) Есть ли способ заставить ERB отображать шаблоны для JSON?
Спасибо!