我有
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 不正确。我需要更新它们以始终保持同步。
我知道 slugs 的概念是保持一个唯一一致的字符串,永不改变。 我理解这一点,但这不是我需要的工作方式。
我知道在 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
有人可以帮我吗?
只需确保您的方法在需要时返回
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">]
# ^^^^^^^^^