ruby-on-rails friendly_id和acts_as_paranian创建重复的插件

aiqt4smr  于 2022-12-15  发布在  Ruby
关注(0)|答案(3)|浏览(108)

我目前在一个模型上使用acts_as_paranian和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代码本身已经使用unscoped时,试图找到一个有效的鼻涕虫。

isr3a4wc

isr3a4wc1#

在模型中添加以下内容可以覆盖对蛞蝓的依赖销毁

def has_many_dependent_for_slugs; end

解决方案来自于对这个github issue的评论。

yfjy0ee7

yfjy0ee72#

Friendly_id有一个名为scoped的模块,它允许你在一个范围内生成唯一的slug。

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

就能解决问题。

zkure5ic

zkure5ic3#

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

解决方案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

相关问题