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
Adminmodule, so it will be accessible under the/adminnamespace.
- The controller is defined within the
-
Index Action:
- The
indexaction retrieves allPagerecords and orders them by theslugcolumn.
- The
-
Edit Action:
- The
editaction finds thePagerecord by itsslugand prepares it for editing.
- The
-
Update Action:
- The
updateaction updates thePagerecord with the provided parameters. If the update is successful, it redirects to theindexaction with a success notice. If the update fails, it re-renders theeditview.
- The
-
Private Methods:
set_page: This method is used as abefore_actioncallback to find thePagerecord by itsslug. If the record is not found, it redirects to theindexaction with an alert.page_params: This method uses strong parameters to allow only thetitle,content, andslugattributes 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
endThis will generate the following routes:
GET /admin/pages=>admin/pages#indexGET /admin/pages/:slug/edit=>admin/pages#editPATCH/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.erbapp/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::RecordNotFoundexception 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::RecordNotFoundexception, it is rescued, and anActionController::RoutingErrorwith 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_pagecallback will attempt to find thePagewith the givenslug. - If no such
Pageexists,find_by!raises anActiveRecord::RecordNotFoundexception. - The
rescueblock 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
endTo test this behavior, you can:
- Start your Rails server.
- Visit a URL like
/admin/pages/nonexistent-slug/editin your browser or use a tool likecurlor 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.