Skip to content

Commit 5203ea9

Browse files
committed
Add wildcard_url validation to page model
To ease the complexity of the page_finder it is required, that the parameter key is unique for all page layouts. This requirement is reducing the searching complexity and also prevent edge cases where different page_layouts in the same tree can have multiple times the same parameter name (e.g. :id).
1 parent 24c2c82 commit 5203ea9

3 files changed

Lines changed: 52 additions & 0 deletions

File tree

app/models/alchemy/page/page_naming.rb

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ module PageNaming
2020
validates :urlname,
2121
uniqueness: {scope: [:language_id, :layoutpage], if: -> { urlname.present? }, case_sensitive: false},
2222
exclusion: {in: RESERVED_URLNAMES}
23+
validate :unique_wildcard_param_keys, if: :has_wildcard_url?
2324

2425
after_update :update_descendants_urlnames,
2526
if: :saved_change_to_urlname?
@@ -55,6 +56,23 @@ def has_wildcard_url?
5556

5657
private
5758

59+
def unique_wildcard_param_keys
60+
key = wildcard_url.param_key
61+
62+
conflicting = PageDefinition.all.find do |other|
63+
other.name != page_layout && other.wildcard_url&.param_key == key
64+
end
65+
66+
if conflicting
67+
errors.add(
68+
:page_layout,
69+
:conflicting_wildcard_param_key,
70+
param_key: key,
71+
conflicting_layout: conflicting.name
72+
)
73+
end
74+
end
75+
5876
def update_descendants_urlnames
5977
reload
6078
descendants.each(&:update_urlname!)

config/locales/alchemy.en.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -834,6 +834,8 @@ en:
834834
base:
835835
restrict_dependent_destroy:
836836
has_many: "There are still %{record} attached to this page. Please remove them first."
837+
page_layout:
838+
conflicting_wildcard_param_key: "has a conflicting wildcard param key \":%{param_key}\" already used by the \"%{conflicting_layout}\" page layout"
837839
descendants:
838840
still_attached_to_nodes: "The following descendant pages are still attached to menu nodes: %{page_names}. Please remove them first."
839841
alchemy/element:

spec/models/alchemy/page_spec.rb

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1933,6 +1933,38 @@ module Alchemy
19331933
end
19341934
end
19351935

1936+
context "with conflicting wildcard param keys across layouts" do
1937+
let(:parent) { create(:alchemy_page, name: "Items") }
1938+
1939+
before do
1940+
PageDefinition.add(
1941+
name: "conflicting_layout",
1942+
wildcard_url: ":id"
1943+
)
1944+
end
1945+
1946+
after { PageDefinition.reset! }
1947+
1948+
it "is invalid when another layout already uses the same param key" do
1949+
page = build(:alchemy_page, parent: parent, name: "Item", page_layout: "conflicting_layout")
1950+
expect(page).not_to be_valid
1951+
expect(page.errors[:page_layout]).to include(
1952+
a_string_matching(/param key ":id".*"product_detail"/)
1953+
)
1954+
end
1955+
end
1956+
1957+
context "with the same wildcard layout under different parents" do
1958+
let(:parent_a) { create(:alchemy_page, name: "Section A") }
1959+
let(:parent_b) { create(:alchemy_page, name: "Section B") }
1960+
1961+
it "allows creating pages with the same layout" do
1962+
create(:alchemy_page, parent: parent_a, name: "Detail A", page_layout: "product_detail")
1963+
page_b = build(:alchemy_page, parent: parent_b, name: "Detail B", page_layout: "product_detail")
1964+
expect(page_b).to be_valid
1965+
end
1966+
end
1967+
19361968
context "if new urlname exists as a legacy url" do
19371969
it "will delete obsolete legacy_urls" do
19381970
expect(page.urlname).to eq("parentparent/parent/page")

0 commit comments

Comments
 (0)