Recourse

Routes

recourses

recourses :users
recourses :posts, only: %i[index show]
recourses :drafts, except: :destroy

Each line draws what resources draws and defines a controller where the host has none, on the app’s first request rather than while the routes draw. Two combinations read differently: create without new gets a one-click Create button, and destroy without edit gets a Delete on each row.

Nesting

recourses :posts do
  recourses :comments
end

The nested resource lives at /posts/5/comments, answered by Posts::CommentsController, with templates under app/views/posts/comments/. It defaults to only: %i[index new create], lists the parent’s rows, and earns a tab on the parent’s card — 8 comments where the parent keeps a counter cache. A create with no index is a button beside the breadcrumb instead. Nesting inside a plain resources block is refused, since every nested page relies on the namespace.

scope module: and namespace work as in Rails, and a namespace may sit between a block and what it nests: Users::Quick::NotesController for namespace(:quick) { recourses :notes } under users.

Singular resources

recourses :users do
  recourse :profile, only: %i[new create show]
end

recourse draws what Rails’ resource draws: one record at /users/5/profile, read off the parent as user.profile, whether by a has_one or a belongs_to. Routed show, it is a tab on the parent’s card; where the record is missing, show sends the reader to the form, and where it is present, new sends them to the page that reads it. Routed only create or destroy, it is a button beside the breadcrumb, offered only where it makes sense.

Bare actions

recourses :posts do
  recourse :publication, only: :create
end

A name with no class behind it is a verb. The gem draws its button on the parent’s pages, Add publication, and the host writes the controller, a RecoursesController like every other:

class Posts::PublicationsController < RecoursesController
  def create
    post = Post.find params.expect(:post_id)
    post.publish!
    redirect_to post_path(post), status: :see_other
  end
end

The two keywords

recourses :tasks, positionable: true
recourses :orders, only: :index, retrievable: true

positionable draws the route a dragged row reports its place to; see Positionable tables. retrievable draws the route a Retrieve button posts to; see Retrievable tables. Both are refused on a resource with no index.

The exit route

resource :session, only: :destroy, as: :exit

A route named exit gives the foot of the sidebar a log-out button. The controller is the host’s.