Neb19
Joined
Activity
Posted in Question about SQL Queries and my routes
Hello
I'm a beginner on Rails and I have questions about my forum project.
I have some Categories which can contain many Themes. And Themes can contain many Topics
Here is what I want with my routes :
localhost/:category_slug
=> categories#show
=> list all Themes inside this Category
localhost/:category_slug/:theme_slug
=> themes#show
=> list all Topics inside this Theme
localhost/:category_slug/:theme_slug/:topic_id
=> topics#show
=> display the corresponding Topic
And I want to render a 404 if one of each resources doesn't exist.
An example if I want to reach the Topic which is associated to my Theme "dark-souls", itself associated to the Category "video-games" :
localhost/video-games/dark-souls/1
.
Moreover, I have a shared view in a helper which contains the list of all my Categories and it's displayed on all my pages.
I successfully did what I want but I dont know if I did it in the good way and I want to know if it's correct or not. I would like to have an external mind and some advises on it.
ApplicationController
class ApplicationController < ActionController::Base
helper_method :current_user
helper_method :is_logged?
helper_method :get_all_categories
def current_user
session[:user_id] || nil
end
def is_logged?
not current_user.nil?
end
def redirect_if_not_logged
is_logged? or redirect_to login_path
end
def render_404
raise ActionController::RoutingError.new("Resource not found")
end
def get_all_categories
@categories = Category.all
end
end
CategoriesController
class CategoriesController < ApplicationController
before_action :redirect_if_not_logged
before_action :get_all_categories, only: :show
def show
@category = Category.includes(:themes).find_by(slug: params[:category_slug])
end
end
ThemesController
class ThemesController < ApplicationController
before_action :redirect_if_not_logged
before_action :get_all_categories, only: :show
def show
@theme = current_category.themes.find_by(slug: params[:theme_slug]) or render_404
end
private
def current_category
Category.includes(themes: :topics).find_by(slug: params[:category_slug]) or render_404
end
end
TopicsController
class TopicsController < ApplicationController
before_action :redirect_if_not_logged
before_action :get_all_categories, only: :show
# GET /:category_slug/:theme_slug/:topic_id
def show
@topic = current_theme.topics.find_by(id: params[:topic_id]) or render_404
end
private
def current_category
Category.includes(themes: :topics).find_by(slug: params[:category_slug]) or render_404
end
def current_theme
current_category.themes.find_by(slug: params[:theme_slug]) or render_404
end
end
Logs
Here are the logs when i try to reach, for instance, /video-games/the-last-of-us-part-2/38
Started GET "/video-games/the-last-of-us-part-2/38" for 127.0.0.1 at 2021-03-16 14:16:52 +0100
Processing by TopicsController#show as HTML
Parameters: {"category_slug"=>"video-games", "theme_slug"=>"the-last-of-us-part-2", "topic_id"=>"38"}
Category Load (0.7ms) SELECT "categories".* FROM "categories" WHERE "categories"."slug" = $1 LIMIT $2 [["slug", "video-games"], ["LIMIT", 1]]
↳ app/controllers/topics_controller.rb:58:in `current_category'
Theme Load (0.7ms) SELECT "themes".* FROM "themes" WHERE "themes"."category_id" = $1 [["category_id", 3]]
↳ app/controllers/topics_controller.rb:58:in `current_category'
Topic Load (0.7ms) SELECT "topics".* FROM "topics" WHERE "topics"."theme_id" IN ($1, $2, $3) [[nil, 1], [nil, 2], [nil, 9]]
↳ app/controllers/topics_controller.rb:58:in `current_category'
Theme Load (0.5ms) SELECT "themes".* FROM "themes" WHERE "themes"."category_id" = $1 AND "themes"."slug" = $2 LIMIT $3 [["category_id", 3], ["slug", "the-last-of-us-part-2"], ["LIMIT", 1]]
↳ app/controllers/topics_controller.rb:62:in `current_theme'
Topic Load (0.5ms) SELECT "topics".* FROM "topics" WHERE "topics"."theme_id" = $1 AND "topics"."id" = $2 LIMIT $3 [["theme_id", 1], ["id", 38], ["LIMIT", 1]]
↳ app/controllers/topics_controller.rb:8:in `show'
Rendering layout layouts/application.html.erb
Rendering topics/show.html.erb within layouts/application
ActionText::RichText Load (0.8ms) SELECT "action_text_rich_texts".* FROM "action_text_rich_texts" WHERE "action_text_rich_texts"."record_id" = $1 AND "action_text_rich_texts"."record_type" = $2 AND "action_text_rich_texts"."name" = $3 LIMIT $4 [["record_id", 38], ["record_type", "Topic"], ["name", "content"], ["LIMIT", 1]]
↳ app/views/topics/show.html.erb:8
Rendered topics/show.html.erb within layouts/application (Duration: 2.5ms | Allocations: 1178)
[Webpacker] Everything's up-to-date. Nothing to do
Rendered shared/_aside_user.html.erb (Duration: 0.2ms | Allocations: 118)
Category Load (0.8ms) SELECT "categories".* FROM "categories"
↳ app/views/shared/_aside_infos.html.erb:10
Rendered shared/_aside_infos.html.erb (Duration: 1.9ms | Allocations: 868)
Rendered layout layouts/application.html.erb (Duration: 25.8ms | Allocations: 7657)
Completed 200 OK in 36ms (Views: 24.8ms | ActiveRecord: 4.7ms | Allocations: 12530)
Conclusion
All is working fine. I mean, if I try to access to a theme which exists but under a category path that doesn't exist I get a HTTP 404, so this is what I want. But I don't know if it's really clean. I mean, I would like to know best practices and in my mind it seems good but there are maybe too many SQL requests ?
Does it look like normal for you ? or do I need to change something?
=> Sorry if my english is not good. Thank you to read me