0.0
No release in over 3 years
Seamless integration between Alba and Inertia Rails.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
 Dependencies

Runtime

 Project Readme

Alba::Inertia

Gem Version

Seamless integration between Alba serializers and Inertia Rails.

Features

  • Support for all Inertia prop types: optional, deferred, and merge props
  • Lazy evaluation for efficient data loading on partial reloads
  • Auto-detection of resource classes based on controller/action naming
Built by Evil Martians

Installation

Add to your Gemfile:

gem "alba"
gem "inertia_rails"
gem "alba-inertia"

Usage

Basic Setup

Include Alba::Inertia::Resource in your resource classes:

class ApplicationResource
  include Alba::Resource
  
  # ...

  helper Alba::Inertia::Resource
end

Include Alba::Inertia::Controller in your controllers:

class InertiaController < ApplicationController
  include Alba::Inertia::Controller
end

Defining Inertia Props

Inline inertia: option (recommended)

class CoursesIndexResource < ApplicationResource
  # Simple attributes
  attributes :id, :title

  # Optional prop (loaded only when requested)
  has_many :courses, serializer: CourseResource, inertia: :optional

  # Deferred prop (loaded in separate request)
  has_many :students, serializer: StudentResource, inertia: :defer

  # Deferred with options
  attribute :stats, inertia: { defer: { group: 'analytics', merge: true } } do |object|
    expensive_calculation(object)
  end

  # Merge prop (for partial reloads)
  has_many :comments, serializer: CommentResource, inertia: { merge: { match_on: :id } }

  # Scroll prop with auto-detection.
  # Checks object for `scroll_meta` and `pagy` attributes, or object being a Kaminari collection.
  has_many :items, inertia: :scroll

  # Scroll prop with explicit metadata
  has_many :items, inertia: { scroll: :meta }
  has_many :items, inertia: { scroll: ->(obj) { obj.meta } }
  has_many :items, inertia: { scroll: ->(obj) { obj.meta }, wrapper: 'data' }

  # Once prop
  has_many :plans, inertia: :once
  has_many :plans, inertia: { once: { key: 'active_plans', expires_in: 1.hour, fresh: ->(obj) { obj.fresh? } } }
end

Separate inertia_prop declaration

class CoursesIndexResource < ApplicationResource
  has_many :courses, serializer: CourseResource
  inertia_prop :courses, optional: true

  attribute :stats
  inertia_prop :stats, defer: { merge: true, group: 'analytics' }
end

Controller Integration

class CoursesController < InertiaController
  def index
    @courses = Course.all
    @current_category_id = params[:category_id]
    # Auto-detects CoursesIndexResource and passes instance variables
  end

  def show
    @course = Course.find(params[:id])

    # With a custom component
    render_inertia "Courses/Show"
  end

  def create
    @course = Course.new(course_params)

    if @course.save
      redirect_to courses_path
    else
      # With errors
      render_inertia inertia: { errors: user.errors }
    end
  end
end

Serialization Modes

.to_inertia - For Inertia.js rendering

Returns lazy procs and Inertia prop objects:

resource = CoursesIndexResource.new(courses: @courses)
resource.to_inertia
# => { "courses" => <InertiaRails::OptionalProp>, "stats" => <Proc> }

.as_json - For standard JSON

Returns normal data (Typelizer, API endpoints):

resource = CoursesIndexResource.new(courses: @courses)
resource.as_json
# => { "courses" => [...], "stats" => 42 }

Inheritance

Metadata is inherited from parent resources:

class BaseResource < ApplicationResource
  attribute :created_at, inertia: :optional
end

class CourseResource < BaseResource
  attributes :id, :title
  # Inherits created_at with optional: true
end

Child can override parent metadata:

class ExtendedCourseResource < CourseResource
  inertia_prop :created_at, defer: true  # Override parent's optional: true
end

Configuration

Alba::Inertia.configure do |config|
  # Render with Alba resource class by default
  config.default_render = true

  # Wrap all props in lambdas by default
  config.lazy_by_default = true
end

Advanced Usage

Custom Serializer Selection

render_inertia(serializer: CustomResource)

Custom Props

render_inertia(locals: { custom: 'props'})

Serializer Params

You can pass params to the serializer using the serializer_params option. This is useful for passing context like the current user, permissions, or feature flags:

class CoursesController < InertiaController
  def index
    @courses = Course.all
    render_inertia(serializer_params: { current_user: current_user })
  end
end

In your resource, access params via the params method:

class CoursesIndexResource < ApplicationResource
  attributes :id, :title

  attribute :can_edit do |course|
    params[:current_user]&.can_edit?(course)
  end
end

Default Serializer Params

Override inertia_serializer_params in your controller to provide default params for all Inertia renders:

class ApplicationController < ActionController::Base
  include Alba::Inertia::Controller

  private

  def inertia_serializer_params
    { current_user: current_user, locale: I18n.locale }
  end
end

The serializer_params option in render_inertia will be merged with these defaults (with serializer_params taking precedence).

Naming Convention

The controller integration follows Rails conventions:

# Controller: CoursesController
# Action: index
# Expected Resource: CoursesIndexResource or CoursesIndexSerializer 

# Controller: Admin::UsersController
# Action: show
# Expected Resource: Admin::UsersShowResource or Admin::UsersShowSerializer

Development

After checking out the repo, run bin/setup to install dependencies. Then, run rake spec to run the tests. You can also run bin/console for an interactive prompt that will allow you to experiment.

To install this gem onto your local machine, run bundle exec rake install. To release a new version, update the version number in version.rb, and then run bundle exec rake release, which will create a git tag for the version, push git commits and the created tag, and push the .gem file to rubygems.org.

Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/skryukov/alba-inertia.

License

The gem is available as open source under the terms of the MIT License.