Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support json builders for generating props #133

Open
BilalBudhani opened this issue Oct 11, 2024 · 5 comments
Open

Support json builders for generating props #133

BilalBudhani opened this issue Oct 11, 2024 · 5 comments

Comments

@BilalBudhani
Copy link

From the Rails way of doing things writing props in controllers feels a little out of place, Consider this example from PingCRM

json.data(paged_contacts) do |contact|
   json.(contact, :id, :name, :phone, :city, :deleted_at)
   if contact.organization
     json.organization(contact.organization, :name)
   end
 end

I imagine in a more complicated app, this logic will start growing into multi line conditions making controllers fat.

It would be great if building props json can be pushed to view layer by leveraging existing robust engines like Jbuilder, props_template etc. instead.

For example

class EventsController < ApplicationController
  use_inertia_view_props :jbuilder # <- tell inertia to use jbuilder templating engine 

  def index
    @events = Event.all
    # props -> app/views/events/index.json.jbuilder
  end
end

And

class EventsController < ApplicationController

  def index
    @events = Event.all
    render inertia: 'Events/Index', template: 'index'
    # props -> app/views/events/index.json.jbuilder
  end
end

This would simplify controllers and unlock capabilities of json builder engines for better usability.

Moreover, I see a possibility of projects that already use json builders for sending data to frontends can progressively adapt Inertia by reusing their existing templates.

@jho406
Copy link

jho406 commented Oct 12, 2024

Hi! Author of props_template here!

props_template also has support for deferred props via the defer option. When you use that option you can gather all deferred props using json.deferred! to iterate through through all deferred props to build an inertia 2 response.

You can also extend it and make it specific for inertia using the extension manager here

@BrandonShar
Copy link
Collaborator

This is a super cool idea, I might hack around on it this weekend. I really like the pattern.

@skryukov
Copy link
Contributor

@BrandonShar here's a quick snippet I posted in the Discord (just in case):

class InertiaExampleController < ApplicationController
  def inertia_view_assigns
    template = lookup_context.find_template(action_name, controller_path)
    json = JbuilderTemplate.new(self)
    binding.eval template.source
    json.attributes!
  end

  def index
    # or set config.default_render: true
    render(inertia: true)
  end
end

But to be honest, I'd love to introduce a plugin system here, so we could support different serializers (and allow users to hook into the process as well).

@bknoles
Copy link
Collaborator

bknoles commented Oct 25, 2024

@skryukov are there any analogous plugin systems you have in mind we could use for inspiration?

@dsh0416
Copy link

dsh0416 commented Dec 6, 2024

@skryukov @BrandonShar Brilliant idea. But it seems that if you try to use json.partial! inside your templates, it might raise double rendering errors.

The following code works, but really weird.

def inertia_view_assigns
  return {} unless lookup_context.exists?(action_name, controller_path)

  JSON.parse(render_to_string(formats: [:json]))
end

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants