Удаление элемента тега из базы данных Rails, когда определенный тег больше не используется ни в одном сообщении - PullRequest
0 голосов
/ 26 февраля 2020

Я пишу простое приложение Rails в стиле блога и успешно добавило довольно простую функцию #tags. Проблема, с которой я сталкиваюсь, заключается в том, что я не могу придумать способ удалить теги, которые больше не используются ни в одном сообщении. Например, если я сделаю тег #twitter в первом сообщении, а затем удалю упомянутый пост, тег #twitter останется в моей базе данных, даже если на него нигде не будет ссылаться. Я хотел бы удалить неиспользуемые теги. Третья таблица БД создана для отношения (сообщение имеет много тегов, теги принадлежат многим сообщениям), а отношение между тегом и сообщением имеет вид "has_and_belongs_to_many"

**tag.rb**
class Tag < ApplicationRecord
    has_and_belongs_to_many :posts
end
**post.rb**
belongs_to :user
has_many :likes, dependent: :destroy
    has_many :comments, dependent: :destroy
    has_and_belongs_to_many :tags, dependent: :destroy


    after_create do
        hashtags = self.body.scan(/#\w+/)
        hashtags.uniq.map do |hashtag|
            tag = Tag.find_or_create_by(name: hashtag.downcase.delete('#'))
            self.tags << tag
        end
    end

    before_update do 
        self.tags.clear 
        hashtags = self.body.scan (/#\w+/)
        hashtags.uniq.map do |hashtag|
            tag = Tag.find_or_create_by(name: hashtag.downcase.delete('#'))
            self.tags << tag
        end
    end
from **post_controller.rb**
 def hashtags 
    tag = Tag.find_by(name: params[:name])
    @posts = tag.posts.page(params[:page])
  end
**schema.rb**
  create_table "posts", force: :cascade do |t|
    t.string "title"
    t.text "body"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.integer "user_id"
    t.string "image_filename"
    t.string "posts"
    t.string "image"
  end

  create_table "posts_tags", id: false, force: :cascade do |t|
    t.bigint "post_id"
    t.bigint "tag_id"
    t.index ["post_id"], name: "index_posts_tags_on_post_id"
    t.index ["tag_id"], name: "index_posts_tags_on_tag_id"
  end

  create_table "tags", force: :cascade do |t|
    t.string "name"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
  end

1 Ответ

0 голосов
/ 26 февраля 2020

Одним из способов создания тегов было создание модели и таблицы Tag, а затем модели и таблицы Taggings.

tag.rb

class Tag < ApplicationRecord

  has_many :taggings
  has_many :posts, through: :taggings

end

tagging.rb

class Tagging < ApplicationRecord
  belongs_to :tag
  belongs_to :post
end

post.rb

class Post < ApplicationRecord
  has_many :taggings
  has_many :tags, through: :taggings
end

Так что теперь у вас есть только таблица соединения который использует post_id и tag_id для соединения двух. Таким образом, вы можете принудительно установить uniq в своей таблице тегов, чтобы избежать избыточных тегов. Как упоминалось выше, вы можете создать метод after_destroy, который удаляет тег после проверки, чтобы увидеть, используется ли он где-либо еще. Или, как упомянул Дэйв Ньютон, держите его для исторических целей c для предложений автозаполнения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...