You are interested for the most part not that messages are deleted when they expire, but that they are not shown .
If you want to make a custom lifetime, it is better to create an expires_at field, where you specify from which point the message should be deleted.
And then make skoup like this:
scope :actual, -> { where("CURRENT_TIMESTAMP > expires_at") }
Use this scop for read operations, and from the user's point of view, it will look as if expired messages are being deleted. Namely , you can delete them by making a task that starts at fixed intervals in any way you like: kroner, external scheduler, background queue with a schedule that you want.
Since the requests to this field will be almost constant, make sure that the database has the necessary indices.
This, however, is an indirect decision. A more direct solution would be to use a data warehouse that supports the lifetime within itself. But as far as I know, ActiveRecord does not support any such. And the benefits of such a decision are small.