I saw the following Qiita article.
The idea of cutting off the source when the error is not resolved -Qiita
I would like you to read the above article for details, but in a simple summary, "If the data in the local environment becomes strange, let's recreate the database (after confirming that it is okay to erase the data)" is.
However, I personally thought, "Well, it's not so good," so I decided to write a reply comment. When I started writing comments, it became quite long, so I decided to make it an independent article. That is this article.
That's why I want to reset everything because the data in the local environment is strange! Here's what you need to do before you think.
(Note: The following content was originally written as a reply comment to Qiita article at the beginning. Please read on that assumption.)
Resetting the database is effective when "it is okay to erase all the data", but it cannot be used otherwise. Rails apps developed as a personal hobby may be good, but Rails apps developed at work often have a lot of "test data that I have used often" even though it is a local environment. It means, "I can't erase all of this." Also, if the same problem occurs in the production environment instead of the development environment, the strategy of "erasing all data" cannot be used.
Furthermore, it becomes difficult to investigate the cause of why the data that caused the error occurred if all the data was erased.
For the reasons mentioned above, "erasing all data" should really be left as a last resort, and as much research and action as possible should be done before erasing the data.
I would take the following remedies.
First, determine the cause of the problem.
In this article, it seems that the cause is that post.user
is nil
.
Then determine if the condition is valid.
When post.user
is nil
, it means that there is no contributor associated with the post.
If you think in common sense, I think this is an unlikely situation (= data abnormality).
Then, think about the cause, "Why did a post without a poster come out?" If you don't figure out the cause, even if you recreate the database and get no error, after a while, "posts without posters" may pop up again.
If you normally operate the screen and you can post without a poster, it is a bug, so be sure to modify the code so that the poster is set so that the bug does not recur.
The possible causes and remedies are listed below.
In recent Rails, the related record defined by belongs_to
is required by default, so I think it is unlikely, but if it has ʻoptional: true, remove it. That way, if you try to save a Post with ʻuser
in nil
, you will get a validation error.
app/models/post.rb
class Post < ApplicationRecord
- belongs_to :user, optional: true
+ belongs_to :user
end
Or maybe the Post model was created first, and then some time later another migration added ʻuser_id` to the posts table. In this case, after executing migration, it is necessary to associate some User record with the existing Post record and save it (modify the existing data). If you forget this correspondence, "posts without posters" will be born.
Perhaps the most probable cause is "I deleted the poster's User record after creating the Post record". in this case,
--Do not allow user records with associated Post records to be deleted --Or, if you delete the User record, delete the related Post record as well. --Alternatively, after accepting posts without posters as normal data, a display like "Unsubscribed user" is displayed on the screen.
Such a coping method can be considered.
The first two can be set with Rails' dependent
option.
See the following articles for details.
Difference between: dependent:: restrict \ _with \ _ error and: restrict \ _with \ _exception -Qiita
This is the only cause that comes to my mind, but if I find another cause (= defect) that "this was the cause", I will modify the program so that "posts without posters" will not be created again in the future.
If you can create a situation where strange data is not generated, it is time to correct the existing abnormal data. For example, you can set the poster for "Post without poster" by executing the following script. (This is just an example, so please modify the script as appropriate.)
user = User.first
Post.all.each do |post|
if post.user.nil?
post.user = user
post.save!
end
end
Alternatively, data correction such as deleting "posts without posters" is also an option.
Post.all.each do |post|
if post.user.nil?
post.destroy!
end
end
By doing this, the poster will be linked to all posts, so calling post.user.image_name
should not cause an error.
If the situation that "there is no contributor associated with the post" is not a problem (valid as a specification), it is necessary to separate the view processing depending on whether post.user
is nil
.
<% if post.user %>
<%#Processing when there is a poster%>
<% else %>
<%#Processing when there is no poster%>
<% end %>
If you deal with it in this way, you can avoid taking the measure of "erasing all data". Or rather, I think it's usually appropriate to take this approach, except when you say, "I'm just making it in my local environment as a personal hobby."