Skip to content

Commit 2375e5e

Browse files
committed
improvement: support typeahead/pills for many cardinality relationships
closes #377
1 parent 38b9bfc commit 2375e5e

14 files changed

Lines changed: 1129 additions & 29 deletions

File tree

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
defmodule Demo.Repo.Migrations.AddOfficesAndMemberships do
2+
@moduledoc """
3+
Updates resources based on their most recent snapshots.
4+
5+
This file was autogenerated with `mix ash_postgres.generate_migrations`
6+
"""
7+
8+
use Ecto.Migration
9+
10+
def up do
11+
create table(:offices, primary_key: false) do
12+
add(:id, :uuid, null: false, default: fragment("gen_random_uuid()"), primary_key: true)
13+
add(:name, :text, null: false)
14+
add(:location, :text)
15+
end
16+
17+
create table(:memberships, primary_key: false) do
18+
add(
19+
:user_id,
20+
references(:users,
21+
column: :id,
22+
name: "memberships_user_id_fkey",
23+
type: :uuid,
24+
prefix: "public"
25+
), primary_key: true, null: false)
26+
27+
add(
28+
:office_id,
29+
references(:offices,
30+
column: :id,
31+
name: "memberships_office_id_fkey",
32+
type: :uuid,
33+
prefix: "public"
34+
), primary_key: true, null: false)
35+
end
36+
end
37+
38+
def down do
39+
drop(constraint(:memberships, "memberships_user_id_fkey"))
40+
41+
drop(constraint(:memberships, "memberships_office_id_fkey"))
42+
43+
drop(table(:memberships))
44+
45+
drop(table(:offices))
46+
end
47+
end
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
defmodule Demo.Repo.Migrations.AddOfficeLinks do
2+
@moduledoc """
3+
Updates resources based on their most recent snapshots.
4+
5+
This file was autogenerated with `mix ash_postgres.generate_migrations`
6+
"""
7+
8+
use Ecto.Migration
9+
10+
def up do
11+
create table(:office_links, primary_key: false) do
12+
add(:relationship_type, :text, null: false, default: "partner")
13+
14+
add(
15+
:source_office_id,
16+
references(:offices,
17+
column: :id,
18+
name: "office_links_source_office_id_fkey",
19+
type: :uuid,
20+
prefix: "public"
21+
), primary_key: true, null: false)
22+
23+
add(
24+
:destination_office_id,
25+
references(:offices,
26+
column: :id,
27+
name: "office_links_destination_office_id_fkey",
28+
type: :uuid,
29+
prefix: "public"
30+
), primary_key: true, null: false)
31+
end
32+
end
33+
34+
def down do
35+
drop(constraint(:office_links, "office_links_source_office_id_fkey"))
36+
37+
drop(constraint(:office_links, "office_links_destination_office_id_fkey"))
38+
39+
drop(table(:office_links))
40+
end
41+
end
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
{
2+
"attributes": [
3+
{
4+
"allow_nil?": false,
5+
"default": "nil",
6+
"generated?": false,
7+
"precision": null,
8+
"primary_key?": true,
9+
"references": {
10+
"deferrable": false,
11+
"destination_attribute": "id",
12+
"destination_attribute_default": null,
13+
"destination_attribute_generated": null,
14+
"index?": false,
15+
"match_type": null,
16+
"match_with": null,
17+
"multitenancy": {
18+
"attribute": "org",
19+
"global": true,
20+
"strategy": "attribute"
21+
},
22+
"name": "memberships_user_id_fkey",
23+
"on_delete": null,
24+
"on_update": null,
25+
"primary_key?": true,
26+
"schema": "public",
27+
"table": "users"
28+
},
29+
"scale": null,
30+
"size": null,
31+
"source": "user_id",
32+
"type": "uuid"
33+
},
34+
{
35+
"allow_nil?": false,
36+
"default": "nil",
37+
"generated?": false,
38+
"precision": null,
39+
"primary_key?": true,
40+
"references": {
41+
"deferrable": false,
42+
"destination_attribute": "id",
43+
"destination_attribute_default": null,
44+
"destination_attribute_generated": null,
45+
"index?": false,
46+
"match_type": null,
47+
"match_with": null,
48+
"multitenancy": {
49+
"attribute": null,
50+
"global": null,
51+
"strategy": null
52+
},
53+
"name": "memberships_office_id_fkey",
54+
"on_delete": null,
55+
"on_update": null,
56+
"primary_key?": true,
57+
"schema": "public",
58+
"table": "offices"
59+
},
60+
"scale": null,
61+
"size": null,
62+
"source": "office_id",
63+
"type": "uuid"
64+
}
65+
],
66+
"base_filter": null,
67+
"check_constraints": [],
68+
"create_table_options": null,
69+
"custom_indexes": [],
70+
"custom_statements": [],
71+
"has_create_action": true,
72+
"hash": "7F297562F680E46CE10EEBCB64315254695DFD343ACEB956AFAF9EB0FCB49AED",
73+
"identities": [],
74+
"multitenancy": {
75+
"attribute": null,
76+
"global": null,
77+
"strategy": null
78+
},
79+
"repo": "Elixir.Demo.Repo",
80+
"schema": null,
81+
"table": "memberships"
82+
}
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
{
2+
"attributes": [
3+
{
4+
"allow_nil?": false,
5+
"default": "\"partner\"",
6+
"generated?": false,
7+
"precision": null,
8+
"primary_key?": false,
9+
"references": null,
10+
"scale": null,
11+
"size": null,
12+
"source": "relationship_type",
13+
"type": "text"
14+
},
15+
{
16+
"allow_nil?": false,
17+
"default": "nil",
18+
"generated?": false,
19+
"precision": null,
20+
"primary_key?": true,
21+
"references": {
22+
"deferrable": false,
23+
"destination_attribute": "id",
24+
"destination_attribute_default": null,
25+
"destination_attribute_generated": null,
26+
"index?": false,
27+
"match_type": null,
28+
"match_with": null,
29+
"multitenancy": {
30+
"attribute": null,
31+
"global": null,
32+
"strategy": null
33+
},
34+
"name": "office_links_source_office_id_fkey",
35+
"on_delete": null,
36+
"on_update": null,
37+
"primary_key?": true,
38+
"schema": "public",
39+
"table": "offices"
40+
},
41+
"scale": null,
42+
"size": null,
43+
"source": "source_office_id",
44+
"type": "uuid"
45+
},
46+
{
47+
"allow_nil?": false,
48+
"default": "nil",
49+
"generated?": false,
50+
"precision": null,
51+
"primary_key?": true,
52+
"references": {
53+
"deferrable": false,
54+
"destination_attribute": "id",
55+
"destination_attribute_default": null,
56+
"destination_attribute_generated": null,
57+
"index?": false,
58+
"match_type": null,
59+
"match_with": null,
60+
"multitenancy": {
61+
"attribute": null,
62+
"global": null,
63+
"strategy": null
64+
},
65+
"name": "office_links_destination_office_id_fkey",
66+
"on_delete": null,
67+
"on_update": null,
68+
"primary_key?": true,
69+
"schema": "public",
70+
"table": "offices"
71+
},
72+
"scale": null,
73+
"size": null,
74+
"source": "destination_office_id",
75+
"type": "uuid"
76+
}
77+
],
78+
"base_filter": null,
79+
"check_constraints": [],
80+
"create_table_options": null,
81+
"custom_indexes": [],
82+
"custom_statements": [],
83+
"has_create_action": true,
84+
"hash": "13225D9C2079AEC4E9D60E19A350D85C1A0F7FFA3635546A3FFB85BF54712D64",
85+
"identities": [],
86+
"multitenancy": {
87+
"attribute": null,
88+
"global": null,
89+
"strategy": null
90+
},
91+
"repo": "Elixir.Demo.Repo",
92+
"schema": null,
93+
"table": "office_links"
94+
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
{
2+
"attributes": [
3+
{
4+
"allow_nil?": false,
5+
"default": "fragment(\"gen_random_uuid()\")",
6+
"generated?": false,
7+
"precision": null,
8+
"primary_key?": true,
9+
"references": null,
10+
"scale": null,
11+
"size": null,
12+
"source": "id",
13+
"type": "uuid"
14+
},
15+
{
16+
"allow_nil?": false,
17+
"default": "nil",
18+
"generated?": false,
19+
"precision": null,
20+
"primary_key?": false,
21+
"references": null,
22+
"scale": null,
23+
"size": null,
24+
"source": "name",
25+
"type": "text"
26+
},
27+
{
28+
"allow_nil?": true,
29+
"default": "nil",
30+
"generated?": false,
31+
"precision": null,
32+
"primary_key?": false,
33+
"references": null,
34+
"scale": null,
35+
"size": null,
36+
"source": "location",
37+
"type": "text"
38+
}
39+
],
40+
"base_filter": null,
41+
"check_constraints": [],
42+
"create_table_options": null,
43+
"custom_indexes": [],
44+
"custom_statements": [],
45+
"has_create_action": true,
46+
"hash": "299AF899B5AFD78358CC250CF0B112B69372F91A18354424180E91AA8E749FB2",
47+
"identities": [],
48+
"multitenancy": {
49+
"attribute": null,
50+
"global": null,
51+
"strategy": null
52+
},
53+
"repo": "Elixir.Demo.Repo",
54+
"schema": null,
55+
"table": "offices"
56+
}

dev/resources/accounts/domain.ex

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,5 +14,8 @@ defmodule Demo.Accounts.Domain do
1414

1515
resources do
1616
resource Demo.Accounts.User
17+
resource Demo.Accounts.Office
18+
resource Demo.Accounts.Membership
19+
resource Demo.Accounts.OfficeLink
1720
end
1821
end
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
defmodule Demo.Accounts.Membership do
2+
use Ash.Resource,
3+
domain: Demo.Accounts.Domain,
4+
data_layer: AshPostgres.DataLayer
5+
6+
postgres do
7+
table "memberships"
8+
repo Demo.Repo
9+
end
10+
11+
actions do
12+
default_accept :*
13+
defaults [:create, :read, :update, :destroy]
14+
end
15+
16+
relationships do
17+
belongs_to :user, Demo.Accounts.User do
18+
public? true
19+
primary_key? true
20+
allow_nil? false
21+
end
22+
23+
belongs_to :office, Demo.Accounts.Office do
24+
public? true
25+
primary_key? true
26+
allow_nil? false
27+
end
28+
end
29+
end

0 commit comments

Comments
 (0)