0

I have a function in controller file in which we are rendering response at the end of the function like this:

render_response(template: 'index')

render_response is a custom function in a separate helper file defined like this:

def render_response(options = {})
  options[:status] = build_status_code(options)
  response_json = {
    success: success_status(options[:status]),
    code: options[:status],
    data: build_data(options),
  }
  render json: response_json, status: options[:status]
end

Also, there is a file index.json.builder contains something like this:

hash = { author: { name: "David" } }
json.post do
  json.title "Merge HOWTO"
  json.merge! hash
end 

I want to capture the entire JSON coming from index.json.builder in a variable (let's say json_data )in the controller file. But, I am not able to find the syntax or method for that.
Any leads would be highly appreciated.

Bhawan
  • 2,441
  • 3
  • 22
  • 47

1 Answers1

0

You can try using the logic from JBuilder's test https://github.com/rails/jbuilder/blob/master/test/jbuilder_template_test.rb#L287-L311 I was able to get it working in my controller/console

def build_view(options = {})
    
    lookup_context = ActionView::LookupContext.new([ "app/views/homes/" ], {}, [""]) # REPLACE HERE YOUR VIEW OR PARTIAL DIRECTORY PATH
    controller = self

    view = if ActionView::Base.respond_to?(:with_empty_template_cache)
    ActionView::Base.with_empty_template_cache.new(lookup_context, options.fetch(:assigns, {}), controller)
    else
    ActionView::Base.new(lookup_context, options.fetch(:assigns, {}), controller)
    end

    def view.view_cache_dependencies; []; end

    view
end

result = build_view.render(partial: "show") # name of your partial or view
=> :build_view
  Rendered homes/_show.json.jbuilder (Duration: 0.6ms | Allocations: 174)
=> "{\"post\":{\"title\":\"Merge HOWTO\",\"author\":{\"name\":\"David\"}}}"

that being said rendering data from the views back into the controller is not something I would advise upon, it's not a very easy and light process, to say the least (considering the whole purpose of your rails app is to make your app translate data into views then into your browser which is the opposite route of what you asked)

I do think the better approach here is to pull the JSON building into a class or model or a method then use that method inside your controller and your view


def the_json_data_you_want
  hash = { author: { name: "David" } }
  Jbuilder.new do |json|
    json.post do
      json.title "Merge HOWTO"
      json.merge! hash
    end
  end
end

and to retrieve the JSON you can call the_json_data_you_want.target!

irb(main):7:0> the_json_data_you_want.target!
=> "{\"post\":{\"title\":\"Merge HOWTO\",\"author\":{\"name\":\"David\"}}}"

then you can use it in your contoller and pass it to the view where it will get rendered

there is more documentation here https://github.com/rails/jbuilder

Mshka
  • 1,798
  • 1
  • 10
  • 19