Swaathi Kakarla
Swaathi Kakarla

Reputation: 2443

How to delete a record only if it exists in Rails?

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

Answers (4)

Nithin
Nithin

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

amit_saxena
amit_saxena

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

xlembouras
xlembouras

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

Jay
Jay

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

Related Questions