You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

关联模型属性变更时如何更新Attraction的slug?

关联模型变更时同步Friendly ID Slug问题解决

问题背景

现有Attraction和Venue两个模型,关联关系与Friendly ID配置如下:

# Attraction模型
class Attraction < ApplicationRecord
  belongs_to :venue
  friendly_id :slugged_name_and_venue, use: :slugged
end
# Venue模型
class Venue < ApplicationRecord
  has_many :attractions, dependent: :nullify
  friendly_id :slugged_name_and_location, use: :slugged
end

Attraction的slug依赖关联Venue的name和location_1属性,当这两个属性变更时,Attraction的slug无法自动同步更新。(注:已知此设计不符合slug稳定的常规用法,但业务场景必须如此)

此前尝试的方案未生效,核心原因是Venue更新完成后,其变更记录已被重置,Attraction无法检测到关联模型的属性变化。

解决方案

修改Venue模型

在Venue的更新回调中,直接强制关联的Attraction重新生成并保存slug:

class Venue < ApplicationRecord
  has_many :attractions, dependent: :nullify
  friendly_id :slugged_name_and_location, use: :slugged

  def should_generate_new_friendly_id?
    slug.blank? || name_changed? || location_1_changed?
  end

  # 当name或location_1变更后,同步更新关联Attraction的slug
  after_update :sync_attraction_slugs, if: -> { saved_change_to_name? || saved_change_to_location_1? }

  private

  def sync_attraction_slugs
    attractions.find_each do |attraction|
      # 强制触发slug生成逻辑
      attraction.send(:generate_friendly_id)
      # 保存更新后的slug,若需要模型验证可去掉validate: false
      attraction.save(validate: false)
    end
  end
end

简化Attraction模型的slug生成判断

调整should_generate_new_friendly_id?方法,确保在自身属性变更或关联Venue未完成更新时也能触发slug生成:

class Attraction < ApplicationRecord
  belongs_to :venue
  friendly_id :slugged_name_and_venue, use: :slugged

  def should_generate_new_friendly_id?
    slug.blank? || 
    name_changed? || 
    full_name_changed? || 
    venue_id_changed? || 
    (venue.present? && (venue.name_changed? || venue.location_1_changed?))
  end
end

原理说明

  • 此前方案失效是因为Venue更新完成后,saved_change_to_*会返回false,Attraction无法检测到关联模型的变更;现在直接在Venue的回调中主动触发Attraction的slug生成逻辑,绕过属性变更检测的限制。
  • 使用Friendly ID内部的generate_friendly_id方法强制重新计算slug,确保生成的slug包含Venue最新的属性值。

内容的提问来源于stack exchange,提问作者rctneil

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 09:11:20