Generate a Ruby on Rails controller for a 'Page' resource that is namespaced inside a module called 'Admin'. Implement the index, edit and update actions using path parameter called 'slug' to find the correct model. For the index action sort the pages by the slug column.
-
-
Save pixeltrix/8e6773d13e6406963695a7c1bea762a3 to your computer and use it in GitHub Desktop.
Certainly! Below is an example of a Ruby on Rails controller for a Page
resource that is namespaced inside a module called Admin
. The controller includes the index
, edit
, and update
actions, and it uses a path parameter called slug
to find the correct model. The index
action sorts the pages by the slug
column.
# app/controllers/admin/pages_controller.rb
module Admin
class PagesController < ApplicationController
before_action :set_page, only: [:edit, :update]
# GET /admin/pages
def index
@pages = Page.order(:slug)
end
# GET /admin/pages/:slug/edit
def edit
end
# PATCH/PUT /admin/pages/:slug
def update
if @page.update(page_params)
redirect_to admin_pages_path, notice: 'Page was successfully updated.'
else
render :edit
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_page
@page = Page.find_by(slug: params[:slug])
redirect_to admin_pages_path, alert: 'Page not found.' unless @page
end
# Only allow a trusted parameter "white list" through.
def page_params
params.require(:page).permit(:title, :content, :slug)
end
end
end
-
Namespace and Controller Definition:
- The controller is defined within the
Admin
module, so it will be accessible under the/admin
namespace.
- The controller is defined within the
-
Index Action:
- The
index
action retrieves allPage
records and orders them by theslug
column.
- The
-
Edit Action:
- The
edit
action finds thePage
record by itsslug
and prepares it for editing.
- The
-
Update Action:
- The
update
action updates thePage
record with the provided parameters. If the update is successful, it redirects to theindex
action with a success notice. If the update fails, it re-renders theedit
view.
- The
-
Private Methods:
set_page
: This method is used as abefore_action
callback to find thePage
record by itsslug
. If the record is not found, it redirects to theindex
action with an alert.page_params
: This method uses strong parameters to allow only thetitle
,content
, andslug
attributes to be updated.
To make this controller work, you need to define the routes in your config/routes.rb
file:
# config/routes.rb
Rails.application.routes.draw do
namespace :admin do
resources :pages, param: :slug, only: [:index, :edit, :update]
end
end
This will generate the following routes:
GET /admin/pages
=>admin/pages#index
GET /admin/pages/:slug/edit
=>admin/pages#edit
PATCH/PUT /admin/pages/:slug
=>admin/pages#update
You will also need to create the corresponding views for the index
and edit
actions in the app/views/admin/pages/
directory.
For example:
app/views/admin/pages/index.html.erb
app/views/admin/pages/edit.html.erb
This setup should give you a fully functional Admin::PagesController
with the specified actions.
Modify the controller so that it raises a 404 instead of redirecting to the index action if the page doesn't exist
To modify the controller so that it raises a 404 (Not Found) error instead of redirecting to the index action when a Page
doesn't exist, you can use Rails' rescue_from
mechanism or explicitly raise an ActiveRecord::RecordNotFound
exception. Here's the updated controller:
# app/controllers/admin/pages_controller.rb
module Admin
class PagesController < ApplicationController
before_action :set_page, only: [:edit, :update]
# GET /admin/pages
def index
@pages = Page.order(:slug)
end
# GET /admin/pages/:slug/edit
def edit
end
# PATCH/PUT /admin/pages/:slug
def update
if @page.update(page_params)
redirect_to admin_pages_path, notice: 'Page was successfully updated.'
else
render :edit
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_page
@page = Page.find_by!(slug: params[:slug])
rescue ActiveRecord::RecordNotFound
raise ActionController::RoutingError, 'Not Found'
end
# Only allow a trusted parameter "white list" through.
def page_params
params.require(:page).permit(:title, :content, :slug)
end
end
end
-
find_by!
Instead offind_by
:- The
find_by!
method raises anActiveRecord::RecordNotFound
exception if no record is found. This is more appropriate for raising a 404 error.
- The
-
Rescue and Raise a 404:
- If
find_by!
raises anActiveRecord::RecordNotFound
exception, it is rescued, and anActionController::RoutingError
with the message'Not Found'
is raised. This results in a 404 error being returned to the client.
- If
- When a request is made to a route like
/admin/pages/nonexistent-slug/edit
, theset_page
callback will attempt to find thePage
with the givenslug
. - If no such
Page
exists,find_by!
raises anActiveRecord::RecordNotFound
exception. - The
rescue
block catches this exception and raises anActionController::RoutingError
, which Rails interprets as a 404 error.
No changes are needed in the routes file. The existing routes will work as expected.
# config/routes.rb
Rails.application.routes.draw do
namespace :admin do
resources :pages, param: :slug, only: [:index, :edit, :update]
end
end
To test this behavior, you can:
- Start your Rails server.
- Visit a URL like
/admin/pages/nonexistent-slug/edit
in your browser or use a tool likecurl
or Postman. - You should see a 404 error page (or a JSON response with a 404 status if your app is API-only).
This approach ensures that invalid requests are handled appropriately and consistently with HTTP standards.