inertia-rails icon indicating copy to clipboard operation
inertia-rails copied to clipboard

Auto-serialization of ActiveRecord models

Open seanders opened this issue 3 years ago • 10 comments

Hi there,

One nice feature of ActiveModelSerializer-based rendering is the implicit serialization of instances of ActiveRecord::Base. See: https://github.com/rails-api/active_model_serializers/blob/v0.10.6/docs/general/getting_started.md#rails-integration

Would there be any appetite or interest for this behavior with the inertia renderer?

For example, say we have this render at the end of a controller action:

class SomeController < ApplicationController
  def show
    @post = Post.find(params[:id])
    render(inertia: 'SomeComponent',
      props: { post: @post } # This would implicitly serialize using a corresponding serializer?
    )
  end
end

seanders avatar Jun 20 '21 01:06 seanders

Hey @seanders this is pretty cool! To make sure I understand, are you suggesting this behavior be added within the Inertia gem itself or should we look for a way to make inertia more flexible to allow hooking in 3rd party gems like this?

BrandonShar avatar Feb 12 '22 04:02 BrandonShar

Seems like a great idea to me too! I would say incorporate this into Inertia itself, as this way of working is very "rails like", and it would really complement the way inertia-rails works imho. Thanks for this very cool project.

Edit: After playing a bit more, I'm confused about the benefit. I thought you always needed to specify the wanted fields, thus this idea would be logical/nice. But now I just found out that you can just do:

render inertia: 'articles/Index', props: {articles: Article.all}

Which is basically the same as the request. So never mind my "great idea" addition. But maybe using the unfiltered props syntax might help someone else too.

rogiervandenberg avatar Mar 12 '22 18:03 rogiervandenberg

Hey @seanders have you tried this with an Inertia app?

https://github.com/inertiajs/inertia-rails/blob/master/lib/inertia_rails/renderer.rb#L25

Under the hood, the gem renders the props as locals within a Rails template on the initial page load, and calls render json: props on subsequent "Inertia-fied" requests.

I would expect the "Inertia-fied" requests to behave exactly like the ActiveModel serializer docs you shared. I'm not sure how Rails would serialize them on the initial page load, though.

bknoles avatar Mar 16 '22 16:03 bknoles

Closing this issue due to inactivity. Please feel free to re-open if its still relevant!

BrandonShar avatar Jun 21 '22 14:06 BrandonShar

Hello i think this would be a great feature, but is a hard to acomplish, i have make a small POC to test using AMS, and the result were great. But for work we have to sticky with rails conventions: @seanders @bknoles @BrandonShar

module ActionController
  module Serialization
    [:_render_with_renderer_inertia].each do |renderer_method|
      define_method renderer_method do |resource, options|
        resource_name = resource.split("/").first.to_sym
        props = options[:props][resource_name] || {}
        options.except!(:props, resource_name)
        options.fetch(:serialization_context) do
          options[:serialization_context] = ActiveModelSerializers::SerializationContext.new(request, options)
        end
        serializable_resource = get_serializer(props, options)
        options.merge!(props: {
          resource_name => serializable_resource,
        })
        super(resource, options)
      end
    end
  end
end
def show
    @vacancy = Vacancy.find(params[:id])
    render inertia: "vacancies/show", props: { vacancies: @vacancy,},
                                      serializer: VacancySerializer
end

We need more work to handle plural and singular, and make fault tolerant.

I think its hard do acomplish to be generic and its not worth to inertia-rails it self. I will finish this mokey patch from AMS to my projects, and maybe add to inertia-rails docs, what do you guys think?

interesting to see that this was a topic already 3 years ago. I also was looking for a "nicer" way to jsonify my records into inertia props.

personally, I'd prefer a way to configure inertia with a custom transform method, for example:

# config/initializers/some_initializer.rb
InertiaRails.configure do |config|
  config.serializer = -> (object) {
    MySuperSerializer.serialize(object)
  }
end

buhrmi avatar Apr 10 '24 18:04 buhrmi

Ooh, I really like that setup @buhrmi . Would a single custom serializer make the most sense or maybe some kind of standard of how to specify a serializer?

BrandonShar avatar Apr 10 '24 18:04 BrandonShar

I do think a single custom serializer is sufficient, because that custom serializer can look at the object, and delegate to model-specific serializers. Kinda how AMS doing it (See https://github.com/rails-api/active_model_serializers/tree/0-10-stable?tab=readme-ov-file#high-level-behavior). So for AMS, it would probably look like this:

InertiaRails.configure do |config|
  config.serializer = -> (resource, options = nil) {
    ActiveModelSerializers::SerializableResource.new(resource, options).as_json
  }
end

Unsure how to pass the options. Maybe optionally in the render call, eg render :inertia, props: {..}, options: {..}

buhrmi avatar Apr 10 '24 19:04 buhrmi

These days, I am playing with using jbuilder for inertia props. Is it a good option?

SyedMSawaid avatar Jun 20 '24 16:06 SyedMSawaid

@SyedMSawaid How are you using jbuilder to render the props? I would also like to do this

howdymatt avatar Aug 07 '24 04:08 howdymatt