I have 3 models.
Story, Tag and Tagging.
A Story has many tags through taggings. Here are my models:
**Story.rb**
class Story < ApplicationRecor
has_many :taggings, dependent: :delete_all
has_many :tags, through: :taggings
end
**Tagging.rb**
class Tagging < ApplicationRecord
belongs_to :tag
belongs_to :story
end
**Tag.rb**
class Tag < ApplicationRecord
has_many :taggings
has_many :stories, through: :taggings
end
So when I delete a story, I have dependent: :delete_all on taggings which calls a single SQL delete statement on all taggings associated with a Story. I'd like to also delete all Tags if there are no longer any taggings associated to it. For example, a story has 1 tagging and one tag through the tagging. When I delete that story, that story and tagging are deleted but that tag still remains. I'd like that tag to be removed as well since there are no taggings associated to that tag anymore.
I've tried this:
**Story.rb**
has_many :taggings, dependent: :destroy
has_many :tags, through: :taggings
and this:
**Story.rb**
has_many :taggings, dependent: :destroy
has_many :tags, through: :taggings, dependent: :destroy
Both doesnt work.. Any advice on how to handle this?
You can check the tags using an after_destroy
class Tagging < ApplicationRecord
after_destroy :destroy_unused_tag
private
def destroy_unused_tag
tag.destroy if tag.taggings.empty?
end
end
Your Tagging model might be missing dependant option for tags.
**Story.rb**
has_many :taggings, dependent: :destroy
has_many :tags, through: :taggings
**Tagging.rb**
belongs_to :story
belongs_to :tags, dependent: :destroy
Related
I want to make tagging system with User specific tags, so each user should have access to tags created only by this User.
Relations are:
Package
has_many :taggings
has_many :tags, through: :taggings
Tag
has_many :taggings
has_many :packages, through: :taggings
Tagging
belongs_to :package
belongs_to :tag
What relations should be with User?
Tag
belongs_to :user
User
has_many :tags
Or:
Tagging
belongs_to :user
User
has_many :tags, through: :taggings
Or:
Tagging
belongs_to :user
User
has_many :taggings
I have three models. A collection has many searches through items.
When a collection is destroyed, I'd like its items to be destroyed, but searches to be nullified, since they are still valid objects on their own.
Can this be done?
Here are my models:
class Collection < ApplicationRecord
has_many :searches, through: :items
has_many :items
has_many :searches, through: :suggestions
has_many :suggestions
end
class Item < ApplicationRecord
belongs_to :collection
belongs_to :search
end
class Search < ApplicationRecord
has_many :collections, through: :items
has_many :items
has_many :collections, through: :suggestions
has_many :suggestions
end
You can just delete the items, just add dependent: :destroy to has_many :items.
class Collection < ApplicationRecord
has_many :searches, through: :items
has_many :items, dependent: :destroy
end
After destroying a collection, the item is destroyed but the search will remain.
second solution
You could even apply dependent: :nullify to has_many :searches - getting the same result.
class Collection < ApplicationRecord
has_many :searches, through: :items, dependent: :nullify
has_many :items
end
From the docs:
collection.delete(object, …)
Removes one or more objects from the collection by setting their foreign keys to NULL. Objects will be in addition destroyed if they're associated with dependent: :destroy, and deleted if they're associated with dependent: :delete_all.
If the :through option is used, then the join records are deleted (rather than nullified) by default, but you can specify dependent: :destroy or dependent: :nullify to override this.
I have a self join table on my product model using a model called matches as the join table. What I would like to do is when deleting a product to have the associated product removed but not deleted. Right now I am trying dependent: :destroy which doesn't work, but I know its not what I want because I don't want to delete the self associated product.
product.rb
class Product < ApplicationRecord
...
has_many :variations, -> { order(:order) }, dependent: :destroy
has_and_belongs_to_many :categories
has_and_belongs_to_many :tags
has_many :matches
has_many :matched_products, through: :matches, dependent: :destroy
...
end
match.rb
class Match < ActiveRecord::Base
belongs_to :product
belongs_to :matched_product, class_name: 'Product', dependent: :destroy
has_many :variations, :through => :matched_product
end
I suggest you update your models as follows:
product.rb
class Product < ApplicationRecord
...
has_many :variations, -> { order(:order) }, dependent: :destroy
has_and_belongs_to_many :categories
has_and_belongs_to_many :tags
has_many :matches, dependent: :destroy
has_many :product_matches, class_name: 'Match', foreign_key: :matched_product_id, dependent: :destroy
has_many :matched_products, through: :matches
...
end
This will ensure that all matches records are deleted when deleting a product whether the product is a product or matched_product in the match record. Removing dependent: :destroy from has_many :matched_products will prevent deletion of the, well, matched_products.
match.rb
class Match < ActiveRecord::Base
belongs_to :product
belongs_to :matched_product, class_name: 'Product'
has_many :variations, :through => :matched_product
end
Similar to above, removing dependent: :destroy from belongs_to :matched_product, class_name: 'Product' will prevent deletion of the matched_product.
I'm not sure what has changed getting this error when trying to login:
ERROR: relation "tags" does not exist
LINE 1: SELECT DISTINCT "tags".* FROM "tags" INNER JOIN "taggings" O...
The tag model:
class Tag < ActiveRecord::Base
attr_accessor :unread_count, :user_feeds
has_many :taggings
has_many :feeds, through: :taggings
end
The tagging model:
class Tagging < ActiveRecord::Base
belongs_to :tag
belongs_to :feed
belongs_to :user
end
And the user relationships:
class User < ActiveRecord::Base
has_one :coupon
has_many :subscriptions, dependent: :delete_all
has_many :feeds, through: :subscriptions
has_many :entries, through: :feeds
has_many :imports, dependent: :destroy
has_many :billing_events, as: :billable, dependent: :delete_all
has_many :taggings, dependent: :delete_all
has_many :tags, through: :taggings
has_many :sharing_services, dependent: :delete_all
has_many :unread_entries, dependent: :delete_all
has_many :starred_entries, dependent: :delete_all
has_many :saved_searches, dependent: :delete_all
has_many :actions, dependent: :destroy
belongs_to :plan
end
This error is new and came right after I tried to install the intercom.io gem. I removed the gem, did a gem cleanup, reset the db and still the same error.
Not sure what happened, if anyone has any suggestions I would appreciate it.
Checked missing tables, and that was the problem.
I have implemented blog where I have many to many associations between article and tag. When a article is crated, it would have one to many tags. When I delete article from my application, it does delete its associated tag. I have set
has_many :taggings, :dependent => :destroy
has_many :tags, through: :taggings , :dependent => :destroy
like this in article.rb(model). Do I need to do something else.
tag.rb
class Tag < ActiveRecord::Base
attr_accessible :name
has_many :taggings
has_many :articles, through: :taggings
end
How to get tag deleted when its associated article is deleted from db. Any suggestion.
In your tag.rb, use
belongs_to :article
rather than your current setup