okuramasafumi / alba

Alba is a JSON serializer for Ruby, JRuby and TruffleRuby.
https://okuramasafumi.github.io/alba/
MIT License
934 stars 43 forks source link

Dynamic params #346

Closed janklimo closed 11 months ago

janklimo commented 12 months ago

Curious if there is a way to pass in a dynamic param, e.g. an associated record. Params seem to be static-only but please correct me if I misunderstood.

Here's my simplified setup:

# Models
class Gallery < ApplicationRecord
  belongs_to :setting,
  has_many :images
end

class Image < ApplicationRecord
  belongs_to :gallery
end

# Serializers
  class GallerySerializer
    include Alba::Resource

    attributes :name

    one :setting, resource: SettingSerializer

    many :images, resource: ImageSerializer #, params: { setting: setting } <~~ this would be handy
  end

  class ImageSerializer
    include Alba::Resource

    attributes :position, :caption, :gallery_id, :url, :alt_text

    attribute :regular_src do |image|
      ImageService
        .new(image, params[:setting]) # <~~ required here
        .regular_src
        .apply_watermark
        .apply_quality
        .apply_format
        .apply_seal
        .to_url
    end

    # ...
  end

In summary, galleries belong to a setting and have many images. Every image needs this setting object to build image URLs etc. I'd like to pass this setting object as a param to avoid N+1 when serializing images.

This is possible now like so:

GallerySerializer.new(Gallery.last, params: { setting: Gallery.last.setting }).serialize

However, I think it would be cleaner if you could add the param in the serializer instead.

okuramasafumi commented 12 months ago

Interesting. It's not possible to do so in current API, but if we have something like dynamic_params we can do:

# many :images, resource: ImageSerializer, params: { setting: setting }
many :images, resource: ImageSerializer, dynamic_params: proc do |gallery|
  {setting: gallery.setting}
end

This might be useful in some cases. I'd like to mention that in your case there's no N+1 problem without params since once a gallery is loaded, image.gallery.setting fetches data from memory, not DB.

janklimo commented 11 months ago

This might be useful in some cases. I'd like to mention that in your case there's no N+1 problem without params since once a gallery is loaded, image.gallery.setting fetches data from memory, not DB.

You're 100% right 👍 forgot I didn't have local caching enabled. Perhaps we can close this for now. Can't think of a very good use case for the new API at this time. Maybe we can revisit if other users have a need for it but I believe it's preferable to keep the API lean unless there is a good reason to expand it.

Thanks for the prompt response!