inertiajs / inertia-rails

The Rails adapter for Inertia.js.
https://inertiajs.com
MIT License
529 stars 43 forks source link

Inertia + Rails + React with no API? #26

Closed veeral-patel closed 3 years ago

veeral-patel commented 4 years ago

Hi, thanks for inertia. I'm not getting how you can build a web app with Inertia, Rails, and React with no API.

I understand how you can avoid having endpoints for listing resources - in your controllers, use ActiveRecord to list the resources, and then pass the list of resources as props to inertia.

But how do you avoid having endpoints for creating/updating/deleting resources? The PingCRM examples I've seen have API endpoints for create, update, etc. which are called by the UI.

caseyprovost commented 4 years ago

@veeral-patel the idea I believe is that you call the controller methods the same way you would with rails except you use inertia to handle the success or response. For example I could write a controller to create a todo, which maybe you fire off from the TodoListPage component...but in the controller method I would call redirect_back so that the TodoListPage re-rendered with the state/props passed to it.

I am building a learning project that I am happy to show you to give you some ideas or talk through it. Remember that with Rails and turbolinks you can do similar things out of the box :)

bknoles commented 4 years ago

yea, @veeral-patel the controller will look very similar to a standard Rails app. For a typical resource, you'd have:

class ThingsController < ApplicationController
  def index
    @things = Thing.order(created_at: :desc)
    render inertia: 'ThingsComponent', props: {things: @things.as_json}
  end

  def show
    @thing = Thing.find(params[:id])
    render inertia: 'ThingComponent', props:  {thing: @thing}
  end

  def edit
    @thing = Thing.find(params[:id])
    render inertia: 'EditThingComponent', props:  {thing: @thing}
  end

  def edit
    @thing = Thing.find(params[:id])
    render inertia: 'EditThingComponent', props:  {thing: @thing}
  end

  def update
    @thing = Thing.find(params[:id])
    if @thing.update(params[:thing])
      redirect_to thing_path
    else
      render inertia: 'EditThingComponent', props: {thing: @thing}
    end
  end

  # More actions here
end

The difference between this and a "typical" React/Rails setup is that these aren't "API" style routes that return plain json... they either return a full HTML page (if the request is a full HTML request like during initial page load), OR, if the request is an AJAX request, they return json specially formatted in a way that InertiaJS understands. As @caseyprovost said, this is quite similar to the way Turbolinks works.