Question
What is the difference between member routes and collection routes in Ruby on Rails?
For example, what is the difference between these two route definitions?
resources :photos do
member do
get :preview
end
end
resources :photos do
collection do
get :search
end
end
I do not understand when to use each type of route or how their generated URLs differ.
Short Answer
By the end of this page, you will understand that a member route acts on one existing resource and includes its id, while a collection route acts on the resource list and does not require an id. You will also know how to define, recognize, and use both in Rails controllers and views.
Concept
Rails resource routing starts with the idea that a route usually represents a resource, such as a photo.
resources :photos
This creates standard routes for creating, listing, showing, updating, and deleting photos. Sometimes an application needs an action that is not one of Rails' standard RESTful actions.
For example:
- Preview one specific photo.
- Search across all photos.
Rails provides member and collection blocks for these cases.
A member route operates on one specific record. Because Rails must know which record to use, its URL includes an identifier such as :id.
GET /photos/42/preview
A collection route operates on the entire set of records. It does not target one particular photo, so its URL has no :id.
GET /photos/search
This distinction matters because it determines:
- the URL Rails creates,
- whether
params[:id]is available, - whether the controller action should load one record,
- which route helper Rails generates.
Use these routes only when the action genuinely fits the resource. If an action represents a separate resource or a complex workflow, a separate controller and resource may be clearer.
Mental Model
Think of photos as a photo album.
- A member route is an action on one photograph you picked up from the album: “preview photo 42.” Rails needs to know which photograph, so the URL includes its ID.
- A collection route is an action on the album as a whole: “search the photo album.” Rails does not need a single photo ID.
In short:
- Member = one item.
- Collection = the whole group of items.
Syntax and Examples
A member route is declared inside member do ... end.
resources :photos do
member do
get :preview
end
end
Rails creates a route similar to:
GET /photos/:id/preview
The controller action can use params[:id] to find the requested photo.
class PhotosController < ApplicationController
def preview
@photo = Photo.find(params[:id])
end
end
The corresponding route helper takes a photo or ID:
preview_photo_path(@photo)
# => "/photos/42/preview"
A collection route is declared inside collection do ... end.
resources :photos do
collection do
get :search
end
end
Rails creates a route similar to:
GET /photos/search
There is no photo ID in this URL. The controller commonly reads a query parameter instead.
class PhotosController < ApplicationController
def search
@photos = Photo.where("title LIKE ?", "%#{params[:q]}%")
end
end
The route helper does not need a photo argument:
search_photos_path(q: "sunset")
# => "/photos/search?q=sunset"
For a single custom route, Rails also supports a shorter form:
resources :photos do
get :preview, on: :member
get :search, on: :collection
end
Step by Step Execution
Consider these routes:
resources :photos do
get :preview, on: :member
get :search, on: :collection
end
Request 1: previewing one photo
GET /photos/12/preview
-
Rails matches
/photos/12/previewto the member route. -
Rails sets
params[:id]to"12". -
Rails calls
PhotosController#preview. -
The action finds the one photo:
@photo = Photo.find(params[:id]) -
The response can render a preview for photo 12.
Request 2: searching photos
GET /photos/search?q=beach
-
Rails matches
/photos/searchto the collection route. -
No photo ID is present, so
params[:id]isnil. -
Rails sets
params[:q]to"beach". -
Rails calls
PhotosController#search. -
The action searches the full photo collection:
@photos = Photo.where("title LIKE ?", "%#{params[:q]}%") -
The response renders a list of matching photos.
Real World Use Cases
Good member route examples
These actions need one existing record:
GET /orders/15/invoice— download or view one order's invoice.POST /articles/9/publish— publish one draft article.PATCH /users/7/activate— activate one user account.POST /payments/31/refund— refund one payment.GET /documents/4/download— download one document.
Good collection route examples
These actions apply to a group of records or provide a collection-level interface:
GET /products/search?q=keyboard— search all products.GET /orders/recent— show recent orders.GET /reports/summary— show a summary across all reports.POST /users/import— import multiple users from a file.GET /articles/archive— show an archive of articles.
The key question is: Would the request still make sense without selecting one record first? If yes, it is often a collection action.
Real Codebase Usage
In real Rails applications, custom actions should be named clearly and kept small. The controller usually follows a different pattern for each route type.
Member action: load one record first
A before_action is common when several actions require the same record.
class PhotosController < ApplicationController
before_action :set_photo, only: [:show, :edit, :update, :destroy, :preview]
def preview
render :preview
end
private
def set_photo
@photo = Photo.find(params[:id])
end
end
Collection action: filter or query records
Collection actions often use query parameters, pagination, and filtering.
class PhotosController < ApplicationController
def search
@photos = Photo.order(created_at: :desc)
@photos = @photos.where("title LIKE ?", "%#{params[:q]}%") if params[:q].present?
end
end
Authorization
Authorization often follows the same distinction:
- Member action: authorize a particular record, such as
authorize @photo. - Collection action: authorize access to the resource type or query scope.
Prefer RESTful resources when an action becomes substantial
For example, if “publishing” has its own data, history, permissions, and lifecycle, it may be better modeled as a resource instead of a custom member action.
resources :articles do
resource :publication, only: [:create, :destroy]
end
This produces routes such as POST /articles/:article_id/publication, which can be easier to extend and test.
Common Mistakes
Expecting params[:id] in a collection action
This collection route has no :id segment:
resources :photos do
get :search, on: :collection
end
So this is incorrect:
# Broken: params[:id] is nil for /photos/search
@photo = Photo.find(params[:id])
Use a member route when the action needs a specific photo.
resources :photos do
get :preview, on: :member
end
Forgetting to pass an object to a member helper
# Broken: Rails needs to know which photo to preview.
preview_photo_path
Pass a record or an ID:
preview_photo_path(@photo)
preview_photo_path(42)
Passing a record to a collection helper
# Usually incorrect and unnecessary.
search_photos_path(@photo)
A collection action does not identify one photo. Pass search options instead:
search_photos_path(q: "mountains")
Using a collection route for an action on one record
# Wrong shape for “preview one photo”
resources :photos do
collection do
get :preview
end
end
This creates /photos/preview, with no way to identify the photo through the path. Use member.
Creating too many custom actions
Routes such as approve, reject, archive, reopen, and publish can be valid. But a controller with many unrelated custom actions can signal that the domain needs another resource. Consider whether the action creates or manages something with its own state and behavior.
Comparisons
| Feature | Member route | Collection route |
|---|---|---|
| Acts on | One existing resource | The resource set as a whole |
| URL pattern | /photos/:id/action | /photos/action |
| Example URL | /photos/42/preview | /photos/search |
params[:id] | Available | Not supplied by the route |
| Helper | preview_photo_path(@photo) | search_photos_path |
| Typical purpose | Preview, publish, archive, download | Search, import, recent, summary |
Member route versus nested resource
A member action is suitable for a small operation directly related to a resource:
post :publish, on: :member
A nested resource is often better when the operation has its own data or lifecycle:
resources :articles do
resources :comments
end
For example, a comment is not merely an action called comment; it is a resource that can be created, listed, edited, and deleted.
member block versus on: :member
These definitions are equivalent:
resources :photos do
member do
get :preview
end
end
resources :photos do
get :preview, on: :member
end
Use the block form when defining several routes of the same kind. Use on: when defining one route concisely.
Cheat Sheet
# Standard RESTful routes
resources :photos
# One photo: URL includes :id
resources :photos do
get :preview, on: :member
end
# GET /photos/:id/preview
# preview_photo_path(@photo)
# params[:id]
# All photos: URL has no :id
resources :photos do
get :search, on: :collection
end
# GET /photos/search
# search_photos_path(q: "term")
# params[:id] is nil
- Use member when the action requires one existing record.
- Use collection when the action applies to the list or resource type.
- A member helper needs a record or ID.
- A collection helper normally takes only query parameters or request data.
- Run
bin/rails routesto inspect the exact route names and URL patterns.
FAQ
What is a member route in Rails?
A member route is a custom route that acts on one resource record. Its path includes :id, such as /photos/42/preview.
What is a collection route in Rails?
A collection route is a custom route that acts on the entire resource collection. Its path has no resource ID, such as /photos/search.
Does a member route always use GET?
No. Choose the HTTP verb based on the operation. GET is appropriate for reading, while POST, PATCH, or DELETE may be appropriate for state changes.
resources :articles do
post :publish, on: :member
end
Why does preview_photo_path require a photo argument?
The member route includes :id, so Rails needs a record or ID to construct the URL.
preview_photo_path(@photo)
Why does search_photos_path not require a photo?
A collection route does not contain :id; it targets the photo collection. You can optionally provide query parameters.
search_photos_path(q: "forest")
Can collection routes accept parameters?
Yes. They can receive query parameters, form data, or JSON request bodies. They simply do not receive a resource ID from their route pattern.
How can I see the routes Rails generated?
Run this command in your Rails project:
bin/rails routes
It shows the HTTP verb, URL pattern, controller action, and route helper name.
Mini Project
Description
Build custom routes for a small photo library. Visitors should be able to search the entire library, while an individual photo page should provide a preview action. This demonstrates how URL structure determines whether an action works with one record or a collection.
Goal
Create a PhotosController with a collection search action and a member preview action.
Requirements
- Define
photosas a Rails resource. - Add a
GETcollection route namedsearch. - Add a
GETmember route namedpreview. - Implement
searchso it filters photos by an optionalqquery parameter. - Implement
previewso it loads one photo fromparams[:id].
Keep learning
Related questions
Add a Default Value to an Existing Column in a Rails Migration
Learn how to add or change a default value on an existing database column using Rails Active Record migrations safely.
Calling a Class Method from an Instance in Ruby
Learn how to call a class method from an instance in Ruby using self.class, with examples, pitfalls, and practical usage patterns.
Calling an Overridden Monkey-Patched Method in Ruby
Learn how to call the original method when monkey patching in Ruby, including alias_method patterns, examples, pitfalls, and practical usage.