Hi,
today I was trying to solve a problem with wrong "Download key" link.
Problem is more general and is in a way how we generate JSON data which
are used by backbone for autoupdating a page. In short, problem is that
we generate JSON hash in model (using standard as_json), but we are
adding view-related stuff (links) by calling views helper methods,
example from app/models/instance.rb:
def as_json(options={})
super(options).merge({
:owner => owner.name,
:provider => provider_account ? provider_account.provider.name : '',
:href => Rails.application.routes.url_helpers.instance_path(id),
:instance_key_path => instance_key_path,
})
end
This Rails.application.routes.url_helpers.instance_path doesn't work
properly if rails application runs with some prefix (relative_url_root,
/conductor in our case), helper methods called by this way return paths
w/o prefix part.
There are 2 ways how to deal with this:
1) try to fix links generated from model by:
a) passing prefix as param to as_json method, then prepend it to
generated links (hack)
b) generate links in controller and then pass them as params to
as_json method (smaller hack, but still violates MVC design as there
will be other view-related stuff in model)
2) generate JSON in view template (only for controller/actions used by
backbone) - this means more code, but it is quite clean. Above example
rewritten to template would look like this:
+++ app/views/instances/_list.json.haml:
= @instances.map{|i| json_hash(i)}.to_json.html_safe
+++ app/helpers/instances_helper.rb
module InstancesHelper
def json_hash(inst)
inst.as_json.merge({
:owner => inst.owner.name,
:provider => inst.provider_account ?
inst.provider_account.provider.name : '',
:href => instance_path(inst.id),
:instance_key_path => key_instance_path(inst.id),
})
end
end
Above view/helepr method could be simplified by using gem for creating
json/xml:
https://github.com/nesquena/rabl
But this means adding another gem (not in fedora) and another
dependency, so I'm pesimistic about this ;).
All above methods seem to be not 100% ideal, I would expect something
easier/cleaner but I surprisingly wasn't able to fine better solution -
I would expect that many people hit same problem. But maybe I just used
wrong google queries.
And here comes my question:
What do you think is the best way how to solved this?
If no response, I'll probably use option 2).
Thanks, Jan