Reputation: 2443
I want to delete the tokens I created for a post, when I am deleting the post itself. But if the token does not exist, I don't want Rails to throw an error and stop executing.
Right now, this is how I go about it. I think this code is way too chunky. Is there any neat way to accomplish the same?
DownloadToken.find_by_post_id(post.id).destroy unless DownloadToken.find_by_post_id(@post.id).nil?
Upvotes: 2
Views: 7456
Reputation: 3699
This is one way(old syntax)
DownloadToken.find_by_post_id(post.id).try(:destroy)
Newer syntax in rails:
DownloadToken.find_by(id: post.id).try(:destroy)
With Ruby's safe navigation operator:
DownloadToken.find_by(id: post.id)&.destroy
Upvotes: 16
Reputation: 7614
DownloadToken.find_by_post_id(post.id)&.destroy
Executes destroy
only if the query result is not nil
. It's the abbreviated version of:
token = DownloadToken.find_by_post_id(post.id)
token.destroy if token
Upvotes: 2
Reputation: 8295
If you are certain you 'll handle the post
deletion with its destroy
method, than you can follow Jay's answer and it will work just fine.
If you will use the delete
method on post
you need some extra functionality to handle the download_tokens
.
class DownloadToken < ActiveRecord::Base
def self.remove_post_tokens(the_post_id)
where(post_id: the_post_id).destroy_all
end
end
so your sequence will be:
id = post.id
post.delete #or post.destroy
DownloadToken.remove_post_tokens(id)
That scenario is not purely academic, because the dependent destroy action can be really expensive, eg if you have too many download_tokens, so you would not want it to be in the same transaction as post
's destruction.
Upvotes: 1
Reputation: 503
Look at your Post model; post.rb
Ie.
Class Post < ActiveRecord::Base
has_many :download_tokens, dependent: :destroy
end
Now when you delete a Post object, whatever the association; has_many
, has_one
, it will find the destroy the dependent
also. In this case the DownloadToken(s)
Upvotes: 3