The data registered in the database is given the ID of the primary key, but if that data is deleted, that ID will no longer exist.
There is a : id
in the URL of the product detail page and the member detail page, and by changing this number, the detail page corresponding to the ID of that number will be displayed, but if an ID that does not exist is entered In case of
ActiveRecord::RecordNotFound
Couldn't find model name with'id'=Entered number
Error occurs.
The process to be performed this time is "Display if the ID exists, and redirect if it does not exist".
Ruby 2.5.7 Rails 5.2.4
This time, we will define an action in application_controller and set that action as befor_action in each controller you want to redirect. As for the situation, it is assumed that the process is when the product ID is entered in the URL on the product details page.
application_controller.rb
class ApplicationController < ActionController::Base
def exist_item?
unless Item.find_by(:id params[:id])
redirect_to root_path
end
end
Use the unless statement to perform the processing inside when the conditional expression is false
.
In this case, the find_by method is used to search for the entered numerical value (params [: id]
) from the item IDs, and whether or not it hits is a condition, and if it does not hit (= false)
) Means that the internal process redirect_to root_path
is executed.
Next, set ʻexist?Defined in application_controller.rb to
before_action` in the controller of the product.
items_controller.rb
class ItemsController < ApplicationController
#In the URL:Specify an action including id
before_action :exist_item?, only[:show, :edit, :update, :destroy]
...
def show
...
end
...
end
At this time, the action specified by the option ʻonly:may be only
: show and
: editwith display, but for the time being, add
: update and
: destroyas well. (It is not necessary, but if you forcibly change the parameters in the form and submit it, the error at the beginning will be displayed.) This will perform an action (ʻexist_item?
) That verifies that the ID of the entered item exists before each action.
It is expected that the display speed, which was a weak point before the correction, will be greatly improved.
I would like to continue to verify the comments I received from time to time!
Thank you for reading until the end!
The article before correction is as follows, but it is deprecated.
This time, we will define an action in application_controller and set that action as befor_action in each controller you want to redirect. As for the situation, it is assumed that the process is when the product ID is entered in the URL on the product details page.
application_controller.rb
class ApplicationController < ActionController::Base
def exist?
Item.all.each do |item|
if item.id == params[:id].to_i
return
end
end
redirect_to root_path
end
end
First, use the each statement to get all the product information in order from the product table.
In each, it is verified whether the ʻid of the item is the same as the entered numerical value for each round. (
.To_i is used because the entered number is recognized as a string type and must be aligned with the same integer type as ʻitem.id
.
item.id = 0
params[:id] = "0"
if item.id == params[:id] => false
)
If the item ID and the entered numerical value (params [: id]
) match in each statement, the processing in ʻif,
returnis performed. When a
return is made, the program will skip it and end the action, so the
redirect_to root_pathwill not be executed. On the contrary, if the each statement ends and the numerical value entered in it and the item ID never match, the subsequent
redirect_to root_path` is executed to redirect to any page.
items_controller.rb
class ItemsController < ApplicationController
#In the URL:Specify an action including id
before_action :exist?, only[:show, :edit, :update, :destroy]
...
def show
...
end
...
end
Next, set ʻexist?Defined in application_controller.rb to
before_action in the controller of the product. At this time, the action specified by the option ʻonly:
may be only : show
and: edit
with display, but for the time being, add : update
and: destroy
as well.
(It is not necessary, but if you forcibly change the parameters in the form and submit it, the error at the beginning will be displayed.)
This will perform an action (ʻexist? `) That verifies that the ID of the entered item exists before each action.
This method takes longer to process as the number of records (the number of products in this case) increases. If there are 1,000 products, each statement will be repeated up to 1,000 times, so the display of details pages etc. will be considerably heavy.
There should be another good way, so I will update it as soon as I find it ┏ ○ I would appreciate it if you could let me know in the comments!
Recommended Posts