Skip to content

Commit d24f9d4

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 ca704f2 commit d24f9d4

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?
@@ -68,6 +69,23 @@ def has_wildcard_url?
6869

6970
private
7071

72+
def unique_wildcard_param_keys
73+
wildcard_url.param_keys.each do |key|
74+
conflicting = PageDefinition.all.find do |other|
75+
other.name != page_layout && other.wildcard_url&.param_keys&.include?(key)
76+
end
77+
78+
if conflicting
79+
errors.add(
80+
:page_layout,
81+
:conflicting_wildcard_param_key,
82+
param_key: key,
83+
conflicting_layout: conflicting.name
84+
)
85+
end
86+
end
87+
end
88+
7189
def update_descendants_urlnames
7290
reload
7391
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
@@ -1910,6 +1910,38 @@ module Alchemy
19101910
end
19111911
end
19121912

1913+
context "with conflicting wildcard param keys across layouts" do
1914+
let(:parent) { create(:alchemy_page, name: "Items") }
1915+
1916+
before do
1917+
PageDefinition.add(
1918+
name: "conflicting_layout",
1919+
wildcard_url: ":id"
1920+
)
1921+
end
1922+
1923+
after { PageDefinition.reset! }
1924+
1925+
it "is invalid when another layout already uses the same param key" do
1926+
page = build(:alchemy_page, parent: parent, name: "Item", page_layout: "conflicting_layout")
1927+
expect(page).not_to be_valid
1928+
expect(page.errors[:page_layout]).to include(
1929+
a_string_matching(/param key ":id".*"product_detail"/)
1930+
)
1931+
end
1932+
end
1933+
1934+
context "with the same wildcard layout under different parents" do
1935+
let(:parent_a) { create(:alchemy_page, name: "Section A") }
1936+
let(:parent_b) { create(:alchemy_page, name: "Section B") }
1937+
1938+
it "allows creating pages with the same layout" do
1939+
create(:alchemy_page, parent: parent_a, name: "Detail A", page_layout: "product_detail")
1940+
page_b = build(:alchemy_page, parent: parent_b, name: "Detail B", page_layout: "product_detail")
1941+
expect(page_b).to be_valid
1942+
end
1943+
end
1944+
19131945
context "without a wildcard_url" do
19141946
it "returns the raw urlname even when called with params" do
19151947
expect(page.urlname(id: 42)).to eq(page.urlname)

0 commit comments

Comments
 (0)