Reputation: 1072
When certain actions are performed, I am sending a json message to the client using web sockets. I like to be able to use view helpers in the jbuilder file so that I can nicely format json data.
How would one go about getting view-ready json into a variable in the controller? The best I have come up with is to use render_to_string
, which works, but returns a String
, so I then have to do JSON.parse
, which is a lot of wasted converting, right?
So I have this:
msg = JSON.parse(render_to_string('show'))
which renders show.json.jbuilder
into json and then returns it as a string, which is then parsed back into json.
It works, but it feels so wrong!
Upvotes: 4
Views: 1474
Reputation: 10869
I stumbled around for hours, and also doing things that are just wrong. I have two horrible hacks. First problem I had was trying to use jbuilder to construct json to be stored in a payload that was not in a MVC context, but in a sidekiq worker. Luckily, I only needed one representation so I essentially rebuilt the template in user.rb
Redacted example shown below.
def to_builder
Jbuilder.new do |user|
user.external_id id
user.username username
user.full_name full_name
end
end
And then used
to_user_hash = {}
to_user_hash["user"] = JSON.parse(user.to_builder.target!)
to store the json, incredibly idiotic.
Now even more insane, when I was using active_model_serializers
I was using a sidekiq worker to render a live activities page via websockets and did the following.
class ActivityBroadcasterWorker < ApplicationWorker
sidekiq_options queue: :low, retry: true, backtrace: true
def perform(activity_id)
view = ActionView::Base.new(ActionController::Base.view_paths)
view.class_eval("include Rails.application.routes.url_helpers")
view.extend ApplicationHelper
if activity = PublicActivity::Activity.find_by_id(activity_id)
template = view.render_activity(activity)
ActionCable.server.broadcast('activity_channel', message: template)
end
end
end
Have you found any better solution to simply tell jbuilder here is my resource, and i want to render this view, or this view partial?
Upvotes: 1