Skip to content

Commit 757f033

Browse files
authored
Raise when a reference conflicts with the scope on schema generation (#6489)
* Raise when a reference conflicts with the scope * Add reference-scope conflict test for context generator * Use scope schema key for checking reference and scope conflict on schema generation
1 parent aaa4e24 commit 757f033

File tree

3 files changed

+71
-2
lines changed

3 files changed

+71
-2
lines changed

lib/mix/phoenix/schema.ex

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ defmodule Mix.Phoenix.Schema do
8585
table = opts[:table] || schema_plural
8686
scope = Mix.Phoenix.Scope.scope_from_opts(ctx_app, opts[:scope], opts[:no_scope])
8787
{cli_attrs, uniques, redacts} = extract_attr_flags(cli_attrs)
88-
{assocs, attrs} = partition_attrs_and_assocs(module, attrs(cli_attrs))
88+
{assocs, attrs} = partition_attrs_and_assocs(module, attrs(cli_attrs), scope)
8989
types = types(attrs)
9090
web_namespace = opts[:web] && Phoenix.Naming.camelize(opts[:web])
9191
web_path = web_namespace && Phoenix.Naming.underscore(web_namespace)
@@ -450,7 +450,7 @@ defmodule Mix.Phoenix.Schema do
450450
)
451451
end
452452

453-
defp partition_attrs_and_assocs(schema_module, attrs) do
453+
defp partition_attrs_and_assocs(schema_module, attrs, scope) do
454454
{assocs, attrs} =
455455
Enum.split_with(attrs, fn
456456
{_, {:references, _}} ->
@@ -470,6 +470,8 @@ defmodule Mix.Phoenix.Schema do
470470

471471
assocs =
472472
Enum.map(assocs, fn {key_id, {:references, source}} ->
473+
validate_scope_and_reference_conflict!(scope, key_id)
474+
473475
key = String.replace(Atom.to_string(key_id), "_id", "")
474476
base = schema_module |> Module.split() |> Enum.drop(-1)
475477
module = Module.concat(base ++ [Phoenix.Naming.camelize(key)])
@@ -479,6 +481,17 @@ defmodule Mix.Phoenix.Schema do
479481
{assocs, attrs}
480482
end
481483

484+
defp validate_scope_and_reference_conflict!(
485+
%Mix.Phoenix.Scope{schema_key: reference_key},
486+
reference_key
487+
) do
488+
Mix.raise("""
489+
Reference #{inspect(reference_key)} has the same name as the scope schema key, either skip the reference or pass it with the --no-scope flag.
490+
""")
491+
end
492+
493+
defp validate_scope_and_reference_conflict!(_scope, _source), do: :ok
494+
482495
defp schema_defaults(attrs) do
483496
Enum.into(attrs, %{}, fn
484497
{key, :boolean} -> {key, ", default: false"}

test/mix/tasks/phx.gen.context_test.exs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -576,4 +576,32 @@ defmodule Mix.Tasks.Phx.Gen.ContextTest do
576576
)
577577
end)
578578
end
579+
580+
test "raises when a reference conflicts with the scope", config do
581+
in_tmp_project(config.test, fn ->
582+
with_scope_env(
583+
:phoenix,
584+
[
585+
user: [
586+
default: true,
587+
module: MyApp.Accounts.Scope,
588+
assign_key: :current_scope,
589+
access_path: [:user, :id],
590+
schema_key: :user_id,
591+
schema_type: :binary_id,
592+
schema_table: :users
593+
]
594+
],
595+
fn ->
596+
assert_raise Mix.Error,
597+
~r"Reference :user_id has the same name as the scope schema key, either skip the reference or pass it with the --no-scope flag.",
598+
fn ->
599+
Gen.Context.run(
600+
~w(Blog Post posts title:string user_id:references:users)
601+
)
602+
end
603+
end
604+
)
605+
end)
606+
end
579607
end

test/mix/tasks/phx.gen.schema_test.exs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -663,4 +663,32 @@ defmodule Mix.Tasks.Phx.Gen.SchemaTest do
663663
end
664664
)
665665
end
666+
667+
test "raises when a reference conflicts with the scope", config do
668+
in_tmp_project(config.test, fn ->
669+
with_scope_env(
670+
:phoenix,
671+
[
672+
user: [
673+
default: true,
674+
module: MyApp.Accounts.Scope,
675+
assign_key: :current_scope,
676+
access_path: [:user, :id],
677+
schema_key: :user_id,
678+
schema_type: :id,
679+
schema_table: :users
680+
]
681+
],
682+
fn ->
683+
assert_raise Mix.Error,
684+
~r"Reference :user_id has the same name as the scope schema key, either skip the reference or pass it with the --no-scope flag.",
685+
fn ->
686+
Gen.Schema.run(
687+
~w(Blog.Post blog_posts title:string user_id:references:users)
688+
)
689+
end
690+
end
691+
)
692+
end)
693+
end
666694
end

0 commit comments

Comments
 (0)