Skip to content

Commit a3397b8

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 7c21a94 commit a3397b8

3 files changed

Lines changed: 50 additions & 0 deletions

File tree

app/models/alchemy/page/page_naming.rb

Lines changed: 16 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,21 @@ def has_wildcard_url?
5556

5657
private
5758

59+
def unique_wildcard_param_keys
60+
conflicting = PageDefinition.all.find do |other|
61+
other.name != page_layout && other.wildcard_url == wildcard_url
62+
end
63+
64+
if conflicting
65+
errors.add(
66+
:page_layout,
67+
:conflicting_wildcard_param_key,
68+
param: wildcard_url,
69+
conflicting_layout: conflicting.name
70+
)
71+
end
72+
end
73+
5874
def update_descendants_urlnames
5975
reload
6076
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 \"%{param}\" 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: ":slug"
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 ":slug".*"page_with_wildcard_url"/)
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: "page_with_wildcard_url")
1963+
page_b = build(:alchemy_page, parent: parent_b, name: "Detail B", page_layout: "page_with_wildcard_url")
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)