Skip to content

Commit ecc2f48

Browse files
improvement: support attribute_type on belongs_to_resource (#7)
* feat: support attribute_type on belongs_to_resource Allow callers to specify the FK attribute type when the parent resource does not use the default UUID primary key: belongs_to_resource :post, MyApp.Post, attribute_type: :integer * fix: add missing SetRelationshipSource transformer to SetupBlob --------- Co-authored-by: Zach Daniel <zach@zachdaniel.dev>
1 parent 7c00dd5 commit ecc2f48

6 files changed

Lines changed: 80 additions & 12 deletions

File tree

lib/ash_storage/attachment_resource.ex

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ defmodule AshStorage.AttachmentResource do
7070

7171
defmodule BelongsToResource do
7272
@moduledoc "Represents a belongs_to_resource declaration on an attachment resource."
73-
defstruct [:name, :resource, :__spark_metadata__]
73+
defstruct [:name, :resource, :attribute_type, :__spark_metadata__]
7474
end
7575

7676
@belongs_to_resource %Spark.Dsl.Entity{
@@ -79,7 +79,8 @@ defmodule AshStorage.AttachmentResource do
7979
describe:
8080
"Declares a belongs_to relationship to a parent resource, creating a proper foreign key.",
8181
examples: [
82-
"belongs_to_resource :post, MyApp.Post"
82+
"belongs_to_resource :post, MyApp.Post",
83+
"belongs_to_resource :post, MyApp.Post, attribute_type: :integer"
8384
],
8485
schema: [
8586
name: [
@@ -91,6 +92,12 @@ defmodule AshStorage.AttachmentResource do
9192
type: :module,
9293
required: true,
9394
doc: "The parent resource module."
95+
],
96+
attribute_type: [
97+
type: :any,
98+
required: false,
99+
doc:
100+
"The type of the generated FK attribute. Defaults to `:uuid`. Set to `:integer` if the parent resource uses `integer_primary_key`."
94101
]
95102
],
96103
target: BelongsToResource

lib/ash_storage/attachment_resource/transformers/setup_attachment.ex

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -55,17 +55,25 @@ defmodule AshStorage.AttachmentResource.Transformers.SetupAttachment do
5555
public?: true,
5656
attribute_writable?: true
5757
) do
58-
Enum.reduce(belongs_to_resources, {:ok, dsl_state}, fn %{name: name, resource: resource},
58+
Enum.reduce(belongs_to_resources, {:ok, dsl_state}, fn %{
59+
name: name,
60+
resource: resource,
61+
attribute_type: attribute_type
62+
},
5963
{:ok, dsl_state} ->
60-
Ash.Resource.Builder.add_relationship(
61-
dsl_state,
62-
:belongs_to,
63-
name,
64-
resource,
65-
allow_nil?: true,
66-
public?: true,
67-
attribute_writable?: true
68-
)
64+
opts =
65+
if attribute_type do
66+
[
67+
allow_nil?: true,
68+
public?: true,
69+
attribute_writable?: true,
70+
attribute_type: attribute_type
71+
]
72+
else
73+
[allow_nil?: true, public?: true, attribute_writable?: true]
74+
end
75+
76+
Ash.Resource.Builder.add_relationship(dsl_state, :belongs_to, name, resource, opts)
6977
end)
7078
end
7179
end

test/ash_storage/attachment_resource_test.exs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ defmodule AshStorage.AttachmentResourceTest do
22
use ExUnit.Case, async: true
33

44
alias AshStorage.Test.Attachment
5+
alias AshStorage.Test.IntegerAttachment
56
alias AshStorage.Test.MultiAttachment
67
alias AshStorage.Test.PolymorphicAttachment
78

@@ -106,6 +107,18 @@ defmodule AshStorage.AttachmentResourceTest do
106107
end
107108
end
108109

110+
describe "belongs_to_resource with attribute_type" do
111+
test "generates FK attribute with the specified type" do
112+
attr = Ash.Resource.Info.attribute(IntegerAttachment, :post_id)
113+
assert attr.type == Ash.Type.Integer
114+
end
115+
116+
test "defaults to UUID type when attribute_type is not set" do
117+
attr = Ash.Resource.Info.attribute(Attachment, :post_id)
118+
assert attr.type == Ash.Type.UUID
119+
end
120+
end
121+
109122
describe "common (all modes)" do
110123
test "all have read and destroy actions" do
111124
for resource <- [Attachment, MultiAttachment, PolymorphicAttachment] do

test/support/domain.ex

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ defmodule AshStorage.Test.Domain do
1212
resource AshStorage.Test.ConfigurablePost
1313
resource AshStorage.Test.AnalyzablePost
1414
resource AshStorage.Test.VariantPost
15+
resource AshStorage.Test.IntegerPost
16+
resource AshStorage.Test.IntegerAttachment
1517
resource AshStorage.Test.ExtraAttrsPost
1618
end
1719
end

test/support/integer_attachment.ex

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
defmodule AshStorage.Test.IntegerAttachment do
2+
@moduledoc false
3+
use Ash.Resource,
4+
domain: AshStorage.Test.Domain,
5+
data_layer: Ash.DataLayer.Ets,
6+
extensions: [AshStorage.AttachmentResource]
7+
8+
ets do
9+
private? true
10+
end
11+
12+
attachment do
13+
blob_resource(AshStorage.Test.Blob)
14+
belongs_to_resource(:post, AshStorage.Test.IntegerPost, attribute_type: :integer)
15+
end
16+
17+
attributes do
18+
uuid_primary_key :id
19+
end
20+
end

test/support/integer_post.ex

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
defmodule AshStorage.Test.IntegerPost do
2+
@moduledoc false
3+
use Ash.Resource,
4+
domain: AshStorage.Test.Domain,
5+
data_layer: Ash.DataLayer.Ets
6+
7+
ets do
8+
private? true
9+
end
10+
11+
actions do
12+
defaults [:read, :destroy, create: []]
13+
end
14+
15+
attributes do
16+
integer_primary_key :id
17+
end
18+
end

0 commit comments

Comments
 (0)