Search code examples
ruby-on-railsruby-on-rails-4jbuilder

How to render Jbuidler partials inside a model?


I am trying to render a jbuilder partial in a model like this:

class Reminder < ActiveRecord::Base
  ...
  def fcm_format
    Jbuilder.new do |json|
      json.partial! 'api/v1/gigs/summary', gig: remindable
    end
  end
end

But this gives me the following error.

TypeError: {:gig=>#} is not a symbol nor a string

Is there a way to render a partial inside of a model or a decorator maybe?


Solution

  • A Jbuilder instance does not respond to partial!. partial! is contained in JbuilderTemplate. JbuilderTemplate's constructor is looking for a context before calling super on Jbuilder.new.

    So the solution is to add a context. The problem is that within JbuilderTemplate, the context calls the method render and in models we don't have a built in way to render. So we need to stub out our context with an ActionController::Base object.

    class Reminder < ActiveRecord::Base
    
      # Returns a builder
      def fcm_format
        context = ActionController::Base.new.view_context
        JbuilderTemplate.new(context) do |json|
          json.partial! 'api/v1/gigs/summary', gig: remindable
        end
      end
    
      # Calls builder.target! to render the json
      def as_json
        fcm_format.target!
      end
    
      # Calls builder.attributes to return a hash representation of the json
      def as_hash
        fcm_format.attributes!
      end
    end