【问题标题】:friendly_id slug not generating, but methods being called没有生成friendly_id slug,但调用了方法
【发布时间】:2026-02-16 06:40:01
【问题描述】:

我正在尝试将friendly_id slug 添加到现有的Rails 模型Spree::Variant。 Variant belongs_to Product,它已经有自己的运行良好的 slug(Spree 和这些模型来自第 3 方 gem)。

当我尝试保存 Variant 时,我希望生成一个 slug 并将其保存到数据库中的 slug 字段中,但该字段仍然为 NULL。

这是我的型号代码:

Spree::Variant.class_eval do
  extend FriendlyId
  friendly_id :slug_candidates, :use => :slugged
  validates :slug, length: { minimum: 3 }, allow_blank: true, uniqueness: true

  self.whitelisted_ransackable_attributes = %w[weight sku slug]

  def parent_slug
    self.product.slug
  end

  def option_value_list
    if !self.option_values.nil? && self.option_values.length > 0
      opts = self.option_values.collect{ |v| 
      v.presentation }.join('-')
      return opts
    else
      return ''
    end
  end

  def slug_candidates
    [
      [:parent_slug, :option_value_list],
      [:parent_slug, :option_value_list, :sku]
    ]
  end

  def should_generate_new_friendly_id?
    puts "Is new #{new_record?}, is blank #{slug.blank?}" #Is new false, is blank true when updating test record
    new_record? || slug.blank?
  end

end

通过确保正确定义 should_generate_new_friendly_id? 来回答类似问题,它似乎在这里。我已经验证当我更新记录时它会被调用并返回 True,但该记录仍然没有以 slug 结尾。

我还验证了 option_value_list 被调用,并输出了所需的信息。我的应用程序的一个示例返回值是“Titanium”。

为什么我的 slug 没有创建?我在哪里可以进一步缩小问题范围?

【问题讨论】:

    标签: ruby-on-rails ruby postgresql spree friendly-id


    【解决方案1】:

    我真的不能说我知道解决方案,但要缩小问题范围,您需要检查 Spree::Variant source code,它将 slug 委托给 product 表。

    在产品表上,slug 是一个 has_many 关系,由 use: :history 知道。 (与问题无关)

    问题在于Spree::Core::DelegateBelongsTo#(delegator_for_setter|| delegator_for) 方法,如果表中存在列名,它们会提前返回,而不是相应地读取或更新记录。

    解决这些问题的一种方法(因为我不知道 Spree 是否提供了更好的方法来处理这些问题)是重新定义您的 slug 方法:

    def slug
      read_attribute(:slug)
    end
    
    def slug=(new_slug)
      write_attribute(:slug, new_slug)
    end
    

    希望我能提供帮助。

    【讨论】:

      最近更新 更多