friendly_id并acts_as_paranoid创建重复的 slug



我目前在模型上使用acts_as_paranoid和friendly_id(5.0.1),当我销毁一个模型并尝试创建一个将生成相同 slug 的新模型时,我得到:

ERROR:  duplicate key value violates unique constraint "index_papers_on_slug"

我需要以某种方式获取代码,以检查所有对象范围内是否已经存在 slug,而不仅仅是未删除的对象。

如何让friendly_id在检查 slug 是否已存在时使用with_deleted。我应该指出,我也在使用鼻涕虫历史,这可能会使事情进一步复杂化。

深入挖掘后,我意识到由于我使用的是历史记录,因此 slug 被完全删除,而对象只是被软删除:

DELETE FROM "friendly_id_slugs" WHERE "friendly_id_slugs"."id" = $1  [["id", 9423]]
所以,我

只需要弄清楚如何防止这种情况,我应该没问题,因为看起来friendly_id代码本身在尝试查找有效 slug 时已经在使用unscoped

将以下内容添加到模型中允许我覆盖对 slug 的依赖销毁

def has_many_dependent_for_slugs; end

解决方案来自对此github问题的评论。

Friendly_id有一个名为scoped的模块,它允许你在作用域内生成唯一的 slug。所以,可能

class Paper < ActiveRecord::Base
  extend FriendlyId
  friendly_id :title, :use => :scoped, :scope => :unscoped
end

将解决问题。

我也遇到了这个问题,我想到了两种不同的方法来解决这个问题。

解决方案 1:

使用dependent: false .

friendly_id :title, dependent: false

解决方案:2

克服这个问题,而不会覆盖任何想要避免这种情况的人的依赖destroy

friendly_id gem 使用名为 scope_for_slug_generator 的方法来设置模型范围。这意味着我们可以通过将以下内容添加到 app/config/initializers/friendly_id.rb 来覆盖此方法。

module FriendlyId
  def scope_for_slug_generator
    scope = if self.class.base_class.include?(Paranoia)
      self.class.base_class.unscoped.with_deleted
    else
      self.class.base_class.unscoped
    end
 
    scope = self.class.base_class.unscoped
    scope = scope.friendly unless scope.respond_to?(:exists_by_friendly_id?)
    primary_key_name = self.class.primary_key
      
    scope.where(self.class.base_class.arel_table[primary_key_name].not_eq(send(primary_key_name)))
  end
end

相关内容

  • 没有找到相关文章