当关联属性发生变化时获取 slug 进行更新

问题描述 投票:0回答:1

我有

Attraction
Venue
型号。 他们的协会是:

Attraction
belongs_to :venue
Venue
has_many :attractions, dependent: :nullify

我正在使用

friendly_id
gem 为两者添加子弹。它们添加了:

Attraction
friendly_id :slugged_name_and_venue, use: :slugged
Venue
friendly_id :slugged_name_and_location, use: :slugged

我遇到的问题是,由于 Attraction slug 包含

name
关联的
location_1
venue
属性,如果
name
location_1
属性发生更改,则 Attraction 的 slug 不正确。我需要更新它们以始终保持同步。

  1. 我知道 slugs 的概念是保持一个唯一一致的字符串,永不改变。 我理解这一点,但这不是我需要的工作方式。

  2. 我知道在 slug 中包含关联值也是一个坏主意,但在这种情况下我需要这个。我通常不这样做。

我尝试了各种不同的选项,但没有一个能够真正成功地更新相关的吸引力。

我最近的尝试是这样的:

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

    after_update :update_attraction_slugs, if: :should_update_attraction_slugs?

  private

  def should_update_attraction_slugs?
    saved_change_to_name? || saved_change_to_location_1?
  end

  def update_attraction_slugs
    attractions.find_each(&:save)
  end
Attraction
    def should_generate_new_friendly_id?
        slug.blank? || slug_changed? || name_changed? || full_name_changed? || venue_id_changed? || venue_name_or_location_1_changed?
    end

  def venue_name_or_location_1_changed?
    saved_change_to_attribute?(:venue_id) || venue.saved_change_to_name? || venue.saved_change_to_location_1?
  end

有人可以帮我吗?

ruby-on-rails associations slug friendly-id
1个回答
0
投票

只需确保您的方法在需要时返回

true

class Venue < ApplicationRecord
  has_many :attractions, dependent: :destroy

  after_update :update_attraction_slugs, if: :should_update_attraction_slugs?

  def should_update_attraction_slugs?
    saved_change_to_name? || saved_change_to_location_1?
  end

  def update_attraction_slugs
    attractions.find_each(&:save)
  end
end
class Attraction < ApplicationRecord
  extend FriendlyId

  belongs_to :venue

  friendly_id :slugged_name_and_venue, use: :slugged

  def slugged_name_and_venue
    "#{venue.name} #{venue.location_1}"
  end

  # `saved_change_to_attribute?(:venue_id)` doesn't work on creation
  def should_generate_new_friendly_id?
    venue_id_changed? || venue.saved_change_to_name? || venue.saved_change_to_location_1?
  end
end
>> Venue.create!(name: "ven1", location_1: "loc1")
=> #<Venue:0x00007fd62fbaf650 id: 6, name: "ven1", location_1: "loc1">

>> Venue.first.attractions.create!
=> #<Attraction:0x00007fd62fd15bc0 id: 1, venue_id: 6, slug: "ven1-loc1">
#                                                             ^^^^^^^^^

>> Venue.first.update!(name: "ven2")
  Venue Load (0.2ms)  SELECT "venues".* FROM "venues" ORDER BY "venues"."id" ASC LIMIT ?  [["LIMIT", 1]]
  TRANSACTION (0.1ms)  begin transaction
  Venue Update (0.4ms)  UPDATE "venues" SET "name" = ? WHERE "venues"."id" = ?  [["name", "ven2"], ["id", 6]]
  Attraction Load (0.1ms)  SELECT "attractions".* FROM "attractions" WHERE "attractions"."venue_id" = ? ORDER BY "attractions"."id" ASC LIMIT ?  [["venue_id", 6], ["LIMIT", 1000]]
  Attraction Exists? (0.1ms)  SELECT 1 AS one FROM "attractions" WHERE "attractions"."id" != 1 AND "attractions"."slug" = ? LIMIT ?  [["slug", "ven2-loc1"], ["LIMIT", 1]]
  Attraction Exists? (0.1ms)  SELECT 1 AS one FROM "attractions" WHERE "attractions"."id" != 1 AND "attractions"."slug" = ? LIMIT ?  [["slug", "ven2-loc1"], ["LIMIT", 1]]
  Attraction Update (0.1ms)  UPDATE "attractions" SET "slug" = ? WHERE "attractions"."id" = ?  [["slug", "ven2-loc1"], ["id", 1]]
  TRANSACTION (0.1ms)  commit transaction
=> true

>> Venue.first.attractions
=> [#<Attraction:0x00007fd62fba7810 id: 1, venue_id: 6, slug: "ven2-loc1">]
#                                                              ^^^^^^^^^
© www.soinside.com 2019 - 2024. All rights reserved.