As a little background, I am in the early stages of designing a large RoR project for the company I work for, and we plan to stick to Rails for the next 5-10 years. We are at this point in the project, we are trying to get some good practices and set up a structure to work for what we need. We examined the pros / cons of transitioning with a full-featured web application (Backbone.js style) versus the static limited JS-based Rails application. Although we would love with webapp, I decided that with Backbone.js it would call:
- Full duplication of views and routes (a maintenance problem in the end)
- Difficulties in tracking polymorphic associations and their routes
- Will not allow us to use view assistants on the client side (service problem)
- Duplication of some model information
- Slow client computers (out of our control) that have difficulty starting it.
To try to reduce this, we decided to go with a more hybrid approach, but for more logic, return to the server side, while still preserving the RESTFUL architecture as an API, as well as possible. We plan to perform initial page loading usually using Rails, and then any manipulations on the page are sent to request via AJAX and get back a JSON object that contains a partial part and some additional information (for example, flash updates, JSON representation of an object, additional JS includes if necessary, etc.)
The problem we are facing is that, as I understand it, we cannot support the RESTFUL architecture and have several partials / views for the same data. As an example, if I wanted to request a list of Orders from the server via orders / index, this returns only one kind of data. If I had an extended table, list, or some other kind / partial / widget that I wanted to request partially for use.
params [: partial] (
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
ActionController::Renderers.add :json do |json, options|
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
}
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?
!