Implementing a NullObject Template in Rails

I am an application where Post belongs_to :user I want to save messages to remote users. This can cause errors in the view when viewing a message whose author was deleted. I tried to do this:

 class Post < ActiveRecord::Base belongs_to :author, class_name: 'User', foreign_key: 'user_id' def author author || NullUser.new super end end 

This results in a "stack level" error. What for? I could do this:

 class Post < ActiveRecord::Base belongs_to :user def author user || NullUser.new end def author=(user) self.user = user end end 

But it seems that this is not the case with my associations. What is the best way to do this?

+6
source share
2 answers

To answer your question,

 1. def author 2. author || NullUser.new 3. super 4. end 

On line 1, you define the author method. Then, on line 2, you call this author method again! This continues to happen, and you get too high a stack level. The correct way to do this is:

 def author super || NullUser.new end 

So, you no longer call the author method inside yourself. You just call the superclass or return NullUser. If you cause a null error when calling super , add an extra nil check:

 def author (super || NullUser.new) rescue NullUser.new end 

The rescue operator will catch all the errors and then return NullUser.new, so you don’t have to worry about the super throwing an error.

EDIT:

Another way to deal with a super throwing exception that looks better:

 def author (super rescue nil) || NullUser.new end 
+13
source

If you want to keep messages for remote users, it is better not to "delete" them.

An alternative is “soft removal”. Just add a boolean column, say “deleted” or “inactive”.

So, when you are about to delete a user, check to see if they have messages. If nothing, it is difficult to remove it. If there is, soft removal.

Thus, everything will be much simpler and clean.

Another way is to "steal" messages. When deleting a user, move all his messages to a special user account, and then delete him.

In any case, you will not break the connection.

+2
source

Source: https://habr.com/ru/post/947375/


All Articles