mirror of
https://github.com/ash-project/ash.git
synced 2024-09-19 13:03:02 +12:00
working on defaults, updating error messages
This commit is contained in:
parent
941359bb8f
commit
a2e007697a
19 changed files with 126 additions and 61 deletions
|
@ -62,3 +62,4 @@ Ash is an open source project, and draws inspiration from similar ideas in other
|
|||
* Validate that all relationships on all resources in the API have destinations *in* that API, or don't and add in logic to pretend those don't exist through the API.
|
||||
* Make authorization spit out informative errors (at least for developers)
|
||||
* Use telemetry and/or some kind of hook system to add metrics
|
||||
* Forbid impossible auth/creation situations (e.g "the id field is not exposed on a create action, and doesn't have a default, therefore writes will always fail.)
|
||||
|
|
|
@ -65,9 +65,23 @@ defmodule Ash.Actions.Create do
|
|||
|> Ash.attributes()
|
||||
|> Enum.map(& &1.name)
|
||||
|
||||
# Map.put_new(attributes, :id, Ecto.UUID.generate())
|
||||
|
||||
attributes_with_defaults =
|
||||
resource
|
||||
|> Ash.attributes()
|
||||
|> Stream.filter(&(not is_nil(&1.default)))
|
||||
|> Enum.reduce(attributes, fn attr, attributes ->
|
||||
if Map.has_key?(attributes, attr.name) do
|
||||
attributes
|
||||
else
|
||||
Map.put(attributes, attr.name, default(attr))
|
||||
end
|
||||
end)
|
||||
|
||||
resource
|
||||
|> struct()
|
||||
|> Ecto.Changeset.cast(Map.put_new(attributes, :id, Ecto.UUID.generate()), allowed_keys)
|
||||
|> Ecto.Changeset.cast(attributes_with_defaults, allowed_keys)
|
||||
|> case do
|
||||
%{valid?: true} = changeset ->
|
||||
{:ok, changeset}
|
||||
|
@ -78,6 +92,10 @@ defmodule Ash.Actions.Create do
|
|||
end
|
||||
end
|
||||
|
||||
defp default(%{default: {:constant, value}}), do: value
|
||||
defp default(%{default: {mod, func}}), do: apply(mod, func, [])
|
||||
defp default(%{default: function}), do: function.()
|
||||
|
||||
defp prepare_create_relationships(changeset, _resource, _relationships) do
|
||||
{:ok, changeset}
|
||||
# relationships
|
||||
|
|
|
@ -41,7 +41,7 @@ defmodule Ash.Api do
|
|||
```
|
||||
|
||||
Then you can interact through that Api with the actions that those resources expose.
|
||||
For example: `MyApp.Api.create(OneResource, %{attributes: %{name: "thing"}}), or
|
||||
For example: `MyApp.Api.create(OneResource, %{attributes: %{name: "thing"}})`, or
|
||||
`MyApp.Api.read(OneResource, %{filter: %{name: "thing"}})`. Corresponding actions must
|
||||
be defined in your resources in order to call them through the Api.
|
||||
"""
|
||||
|
@ -115,7 +115,7 @@ defmodule Ash.Api do
|
|||
max_concurrency:
|
||||
"The total number of side loads (per side load nesting level, per ongoing side load) that can be running. Uses `System.schedulers_online/0` if unset.",
|
||||
timeout:
|
||||
"the maximum amount of time to wait (in milliseconds) without receiving a task reply. see `task.supervisor.async_stream/6",
|
||||
"the maximum amount of time to wait (in milliseconds) without receiving a task reply. see `task.supervisor.async_stream/6`",
|
||||
shutdown:
|
||||
"an integer indicating the timeout value. Defaults to 5000 milliseconds"
|
||||
],
|
||||
|
|
|
@ -29,7 +29,7 @@ defmodule Ash.Resource do
|
|||
default_page_size:
|
||||
"The default page size for any read action. If no page size is specified, this value is used.",
|
||||
primary_key:
|
||||
"If true, a default `id` uuid primary key is used. If false, none is created. See the primary_key opts for info on specifying primary key options."
|
||||
"If true, a default `id` uuid primary key that autogenerates is used. If false, none is created. See the primary_key opts for info on specifying primary key options."
|
||||
],
|
||||
required: [:name, :type],
|
||||
defaults: [
|
||||
|
@ -124,7 +124,12 @@ defmodule Ash.Resource do
|
|||
def define_primary_key(mod, opts) do
|
||||
case opts[:primary_key] do
|
||||
true ->
|
||||
{:ok, attribute} = Ash.Resource.Attributes.Attribute.new(:id, :uuid, primary_key?: true)
|
||||
{:ok, attribute} =
|
||||
Ash.Resource.Attributes.Attribute.new(:id, :uuid,
|
||||
primary_key?: true,
|
||||
default: &Ecto.UUID.generate/0
|
||||
)
|
||||
|
||||
Module.put_attribute(mod, :attributes, attribute)
|
||||
|
||||
false ->
|
||||
|
|
|
@ -28,7 +28,7 @@ defmodule Ash.Resource.Actions do
|
|||
end
|
||||
end
|
||||
|
||||
@doc "Returns an `allow` rule. See `Ash.Authorization.Rule.new/2 for more."
|
||||
@doc "Returns an `allow` rule. See `Ash.Authorization.Rule.new/2` for more."
|
||||
defmacro allow(check, opts \\ []) do
|
||||
quote bind_quoted: [check: check, opts: opts] do
|
||||
case Ash.Authorization.Rule.allow(check, opts) do
|
||||
|
@ -44,7 +44,7 @@ defmodule Ash.Resource.Actions do
|
|||
end
|
||||
end
|
||||
|
||||
@doc "Returns an `allow_unless` rule. See `Ash.Authorization.Rule.new/2 for more."
|
||||
@doc "Returns an `allow_unless` rule. See `Ash.Authorization.Rule.new/2` for more."
|
||||
defmacro allow_unless(check, opts \\ []) do
|
||||
quote bind_quoted: [check: check, opts: opts] do
|
||||
case Ash.Authorization.Rule.allow_unless(check, opts) do
|
||||
|
@ -60,7 +60,7 @@ defmodule Ash.Resource.Actions do
|
|||
end
|
||||
end
|
||||
|
||||
@doc "Returns an `allow_only` rule. See `Ash.Authorization.Rule.new/2 for more."
|
||||
@doc "Returns an `allow_only` rule. See `Ash.Authorization.Rule.new/2` for more."
|
||||
defmacro allow_only(check, opts \\ []) do
|
||||
quote bind_quoted: [check: check, opts: opts] do
|
||||
case Ash.Authorization.Rule.allow_only(check, opts) do
|
||||
|
@ -76,7 +76,7 @@ defmodule Ash.Resource.Actions do
|
|||
end
|
||||
end
|
||||
|
||||
@doc "Returns a `deny` rule. See `Ash.Authorization.Rule.new/2 for more."
|
||||
@doc "Returns a `deny` rule. See `Ash.Authorization.Rule.new/2` for more."
|
||||
defmacro deny(check, opts \\ []) do
|
||||
quote bind_quoted: [check: check, opts: opts] do
|
||||
case Ash.Authorization.Rule.deny(check, opts) do
|
||||
|
@ -92,7 +92,7 @@ defmodule Ash.Resource.Actions do
|
|||
end
|
||||
end
|
||||
|
||||
@doc "Returns a `deny_unless` rule. See `Ash.Authorization.Rule.new/2 for more."
|
||||
@doc "Returns a `deny_unless` rule. See `Ash.Authorization.Rule.new/2` for more."
|
||||
defmacro deny_unless(check, opts \\ []) do
|
||||
quote bind_quoted: [check: check, opts: opts] do
|
||||
case Ash.Authorization.Rule.deny_unless(check, opts) do
|
||||
|
@ -108,7 +108,7 @@ defmodule Ash.Resource.Actions do
|
|||
end
|
||||
end
|
||||
|
||||
@doc "Returns a `deny_only` rule. See `Ash.Authorization.Rule.new/2 for more."
|
||||
@doc "Returns a `deny_only` rule. See `Ash.Authorization.Rule.new/2` for more."
|
||||
defmacro deny_only(check, opts \\ []) do
|
||||
quote bind_quoted: [check: check, opts: opts] do
|
||||
case Ash.Authorization.Rule.deny_only(check, opts) do
|
||||
|
|
|
@ -1,19 +1,32 @@
|
|||
defmodule Ash.Resource.Attributes.Attribute do
|
||||
@doc false
|
||||
|
||||
defstruct [:name, :type, :primary_key?]
|
||||
defstruct [:name, :type, :primary_key?, :default]
|
||||
|
||||
@type t :: %__MODULE__{
|
||||
name: atom(),
|
||||
type: Ash.type(),
|
||||
primary_key?: boolean()
|
||||
primary_key?: boolean(),
|
||||
default: (() -> term)
|
||||
}
|
||||
|
||||
@schema Ashton.schema(
|
||||
opts: [primary_key?: :boolean],
|
||||
defaults: [primary_key?: false],
|
||||
opts: [
|
||||
primary_key?: :boolean,
|
||||
default: [
|
||||
{:function, 0},
|
||||
{:tuple, {:module, :atom}},
|
||||
{:tuple, {{:const, :constant}, :any}}
|
||||
]
|
||||
],
|
||||
defaults: [
|
||||
primary_key?: false
|
||||
],
|
||||
describe: [
|
||||
primary_key?: "Whether this field is, or is part of, the primary key of a resource."
|
||||
primary_key?:
|
||||
"Whether this field is, or is part of, the primary key of a resource.",
|
||||
default:
|
||||
"A one argument function that returns a default value, an mfa that does the same, or a raw value via specifying `{:constant, value}`."
|
||||
]
|
||||
)
|
||||
|
||||
|
@ -22,17 +35,37 @@ defmodule Ash.Resource.Attributes.Attribute do
|
|||
|
||||
@spec new(atom, Ash.Type.t(), Keyword.t()) :: {:ok, t()} | {:error, term}
|
||||
def new(name, type, opts) do
|
||||
case Ashton.validate(opts, @schema) do
|
||||
{:ok, opts} ->
|
||||
{:ok,
|
||||
%__MODULE__{
|
||||
name: name,
|
||||
type: type,
|
||||
primary_key?: opts[:primary_key?] || false
|
||||
}}
|
||||
with {:ok, opts} <- Ashton.validate(opts, @schema),
|
||||
{:default, {:ok, default}} <- {:default, cast_default(type, opts)} do
|
||||
{:ok,
|
||||
%__MODULE__{
|
||||
name: name,
|
||||
type: type,
|
||||
primary_key?: opts[:primary_key?],
|
||||
default: default
|
||||
}}
|
||||
else
|
||||
{:error, error} -> {:error, error}
|
||||
{:default, _} -> {:error, [{:default, "is not a valid default for type #{inspect(type)}"}]}
|
||||
end
|
||||
end
|
||||
|
||||
{:error, error} ->
|
||||
{:error, error}
|
||||
defp cast_default(type, opts) do
|
||||
case Keyword.fetch(opts, :default) do
|
||||
{:ok, default} when is_function(default, 0) ->
|
||||
{:ok, default}
|
||||
|
||||
{:ok, {mod, func}} when is_atom(mod) and is_atom(func) ->
|
||||
{:ok, {mod, func}}
|
||||
|
||||
{:ok, {:constant, default}} ->
|
||||
case Ash.Type.cast_input(type, default) do
|
||||
{:ok, value} -> {:ok, {:constant, value}}
|
||||
:error -> :error
|
||||
end
|
||||
|
||||
:error ->
|
||||
{:ok, nil}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
2
mix.exs
2
mix.exs
|
@ -49,7 +49,7 @@ defmodule Ash.MixProject do
|
|||
{:ecto, "~> 3.0"},
|
||||
{:ets, "~> 0.8.0"},
|
||||
{:ex_doc, "~> 0.21", only: :dev, runtime: false},
|
||||
{:ashton, "~> 0.3.10"}
|
||||
{:ashton, "~> 0.4.0"}
|
||||
]
|
||||
end
|
||||
end
|
||||
|
|
2
mix.lock
2
mix.lock
|
@ -1,5 +1,5 @@
|
|||
%{
|
||||
"ashton": {:hex, :ashton, "0.3.10", "ce0ab19f154c7fe8fefbc1486fdf7b601a0fa944555284182755197b1c073464", [:mix], [], "hexpm"},
|
||||
"ashton": {:hex, :ashton, "0.4.0", "5d6fd833da9102d72a8b911498b55605282132450598af7e13b681a794067a4c", [:mix], [], "hexpm"},
|
||||
"connection": {:hex, :connection, "1.0.4", "a1cae72211f0eef17705aaededacac3eb30e6625b04a6117c1b2db6ace7d5976", [:mix], [], "hexpm"},
|
||||
"dataloader": {:hex, :dataloader, "1.0.6", "fb724d6d3fb6acb87d27e3b32dea3a307936ad2d245faf9cf5221d1323d6a4ba", [:mix], [{:ecto, ">= 0.0.0", [hex: :ecto, repo: "hexpm", optional: true]}], "hexpm"},
|
||||
"db_connection": {:hex, :db_connection, "2.1.1", "a51e8a2ee54ef2ae6ec41a668c85787ed40cb8944928c191280fe34c15b76ae5", [:mix], [{:connection, "~> 1.0.2", [hex: :connection, repo: "hexpm", optional: false]}], "hexpm"},
|
||||
|
|
|
@ -15,6 +15,11 @@ defmodule Ash.Test.Actions.CreateTest do
|
|||
end
|
||||
end
|
||||
|
||||
defmodule PostDefaults do
|
||||
def garbage2(), do: "garbage2"
|
||||
def garbage3(), do: "garbage3"
|
||||
end
|
||||
|
||||
defmodule Post do
|
||||
use Ash.Resource, name: "posts", type: "post"
|
||||
use Ash.DataLayer.Ets, private?: true
|
||||
|
@ -27,6 +32,9 @@ defmodule Ash.Test.Actions.CreateTest do
|
|||
attributes do
|
||||
attribute :title, :string
|
||||
attribute :contents, :string
|
||||
attribute :tag, :string, default: {:constant, "garbage"}
|
||||
attribute :tag2, :string, default: &PostDefaults.garbage2/0
|
||||
attribute :tag3, :string, default: {PostDefaults, :garbage3}
|
||||
end
|
||||
|
||||
relationships do
|
||||
|
|
|
@ -49,7 +49,7 @@ defmodule Ash.Test.Resource.ApiTest do
|
|||
test "it fails if `interface?` is not a boolean" do
|
||||
assert_raise(
|
||||
Ash.Error.ApiDslError,
|
||||
"`use Ash.Test.Resource.ApiTest.Api, ...` interface? must be of type :boolean",
|
||||
"`use Ash.Test.Resource.ApiTest.Api, ...` interface? must be boolean",
|
||||
fn ->
|
||||
defapi(interface?: 10) do
|
||||
end
|
||||
|
@ -60,7 +60,7 @@ defmodule Ash.Test.Resource.ApiTest do
|
|||
test "it fails if `max_page_size` is not an integer" do
|
||||
assert_raise(
|
||||
Ash.Error.ApiDslError,
|
||||
"`use Ash.Test.Resource.ApiTest.Api, ...` max_page_size must be of type :integer",
|
||||
"`use Ash.Test.Resource.ApiTest.Api, ...` max_page_size must be integer",
|
||||
fn ->
|
||||
defapi(max_page_size: "ten") do
|
||||
end
|
||||
|
@ -82,7 +82,7 @@ defmodule Ash.Test.Resource.ApiTest do
|
|||
test "it fails if `default_page_size` is not an integer" do
|
||||
assert_raise(
|
||||
Ash.Error.ApiDslError,
|
||||
"`use Ash.Test.Resource.ApiTest.Api, ...` default_page_size must be of type :integer",
|
||||
"`use Ash.Test.Resource.ApiTest.Api, ...` default_page_size must be integer",
|
||||
fn ->
|
||||
defapi(default_page_size: "ten") do
|
||||
end
|
||||
|
@ -104,7 +104,7 @@ defmodule Ash.Test.Resource.ApiTest do
|
|||
test "it fails if the parallel_side_load supervisor is not an atom" do
|
||||
assert_raise(
|
||||
Ash.Error.ApiDslError,
|
||||
"option supervisor at parallel_side_load must be of type :atom",
|
||||
"option supervisor at parallel_side_load must be atom",
|
||||
fn ->
|
||||
defapi do
|
||||
parallel_side_load(supervisor: "foo")
|
||||
|
@ -116,7 +116,7 @@ defmodule Ash.Test.Resource.ApiTest do
|
|||
test "it fails if the max_concurrency is not an integer" do
|
||||
assert_raise(
|
||||
Ash.Error.ApiDslError,
|
||||
"option max_concurrency at parallel_side_load must be of type :integer",
|
||||
"option max_concurrency at parallel_side_load must be integer",
|
||||
fn ->
|
||||
defapi do
|
||||
parallel_side_load(supervisor: :foo, max_concurrency: "foo")
|
||||
|
@ -140,7 +140,7 @@ defmodule Ash.Test.Resource.ApiTest do
|
|||
test "it fails if the timeout is not an integer" do
|
||||
assert_raise(
|
||||
Ash.Error.ApiDslError,
|
||||
"option timeout at parallel_side_load must be of type :integer",
|
||||
"option timeout at parallel_side_load must be integer",
|
||||
fn ->
|
||||
defapi do
|
||||
parallel_side_load(supervisor: :foo, timeout: "foo")
|
||||
|
@ -164,7 +164,7 @@ defmodule Ash.Test.Resource.ApiTest do
|
|||
test "it fails if the shutdown is not an integer" do
|
||||
assert_raise(
|
||||
Ash.Error.ApiDslError,
|
||||
"option shutdown at parallel_side_load must be of type :integer",
|
||||
"option shutdown at parallel_side_load must be integer",
|
||||
fn ->
|
||||
defapi do
|
||||
parallel_side_load(supervisor: :foo, shutdown: "foo")
|
||||
|
|
|
@ -48,7 +48,7 @@ defmodule Ash.Test.Dsl.Resource.Actions.CreateTest do
|
|||
test "it fails if `primary?` is not a boolean" do
|
||||
assert_raise(
|
||||
Ash.Error.ResourceDslError,
|
||||
"option primary? at actions -> create -> default must be of type :boolean",
|
||||
"option primary? at actions -> create -> default must be boolean",
|
||||
fn ->
|
||||
defposts do
|
||||
actions do
|
||||
|
@ -62,7 +62,7 @@ defmodule Ash.Test.Dsl.Resource.Actions.CreateTest do
|
|||
test "it fails if `rules` is not a list" do
|
||||
assert_raise(
|
||||
Ash.Error.ResourceDslError,
|
||||
"option rules at actions -> create -> default must be of type {:list, {:struct, Ash.Authorization.Rule}}",
|
||||
"option rules at actions -> create -> default must be [{:struct, Ash.Authorization.Rule}]",
|
||||
fn ->
|
||||
defposts do
|
||||
actions do
|
||||
|
@ -76,7 +76,7 @@ defmodule Ash.Test.Dsl.Resource.Actions.CreateTest do
|
|||
test "it fails if the elements of the rules list are not rules" do
|
||||
assert_raise(
|
||||
Ash.Error.ResourceDslError,
|
||||
"option rules at actions -> create -> default must be of type {:list, {:struct, Ash.Authorization.Rule}}",
|
||||
"option rules at actions -> create -> default must be [{:struct, Ash.Authorization.Rule}]",
|
||||
fn ->
|
||||
defposts do
|
||||
actions do
|
||||
|
|
|
@ -48,7 +48,7 @@ defmodule Ash.Test.Dsl.Resource.Actions.DestroyTest do
|
|||
test "it fails if `primary?` is not a boolean" do
|
||||
assert_raise(
|
||||
Ash.Error.ResourceDslError,
|
||||
"option primary? at actions -> destroy -> default must be of type :boolean",
|
||||
"option primary? at actions -> destroy -> default must be boolean",
|
||||
fn ->
|
||||
defposts do
|
||||
actions do
|
||||
|
@ -62,7 +62,7 @@ defmodule Ash.Test.Dsl.Resource.Actions.DestroyTest do
|
|||
test "it fails if `rules` is not a list" do
|
||||
assert_raise(
|
||||
Ash.Error.ResourceDslError,
|
||||
"option rules at actions -> destroy -> default must be of type {:list, {:struct, Ash.Authorization.Rule}}",
|
||||
"option rules at actions -> destroy -> default must be [{:struct, Ash.Authorization.Rule}]",
|
||||
fn ->
|
||||
defposts do
|
||||
actions do
|
||||
|
@ -76,7 +76,7 @@ defmodule Ash.Test.Dsl.Resource.Actions.DestroyTest do
|
|||
test "it fails if the elements of the rules list are not rules" do
|
||||
assert_raise(
|
||||
Ash.Error.ResourceDslError,
|
||||
"option rules at actions -> destroy -> default must be of type {:list, {:struct, Ash.Authorization.Rule}}",
|
||||
"option rules at actions -> destroy -> default must be [{:struct, Ash.Authorization.Rule}]",
|
||||
fn ->
|
||||
defposts do
|
||||
actions do
|
||||
|
|
|
@ -48,7 +48,7 @@ defmodule Ash.Test.Dsl.Resource.Actions.ReadTest do
|
|||
test "it fails if `primary?` is not a boolean" do
|
||||
assert_raise(
|
||||
Ash.Error.ResourceDslError,
|
||||
"option primary? at actions -> read -> default must be of type :boolean",
|
||||
"option primary? at actions -> read -> default must be boolean",
|
||||
fn ->
|
||||
defposts do
|
||||
actions do
|
||||
|
@ -62,7 +62,7 @@ defmodule Ash.Test.Dsl.Resource.Actions.ReadTest do
|
|||
test "it fails if `rules` is not a list" do
|
||||
assert_raise(
|
||||
Ash.Error.ResourceDslError,
|
||||
"option rules at actions -> read -> default must be of type {:list, {:struct, Ash.Authorization.Rule}}",
|
||||
"option rules at actions -> read -> default must be [{:struct, Ash.Authorization.Rule}]",
|
||||
fn ->
|
||||
defposts do
|
||||
actions do
|
||||
|
@ -76,7 +76,7 @@ defmodule Ash.Test.Dsl.Resource.Actions.ReadTest do
|
|||
test "it fails if the elements of the rules list are not rules" do
|
||||
assert_raise(
|
||||
Ash.Error.ResourceDslError,
|
||||
"option rules at actions -> read -> default must be of type {:list, {:struct, Ash.Authorization.Rule}}",
|
||||
"option rules at actions -> read -> default must be [{:struct, Ash.Authorization.Rule}]",
|
||||
fn ->
|
||||
defposts do
|
||||
actions do
|
||||
|
|
|
@ -48,7 +48,7 @@ defmodule Ash.Test.Dsl.Resource.Actions.UpdateTest do
|
|||
test "it fails if `primary?` is not a boolean" do
|
||||
assert_raise(
|
||||
Ash.Error.ResourceDslError,
|
||||
"option primary? at actions -> update -> default must be of type :boolean",
|
||||
"option primary? at actions -> update -> default must be boolean",
|
||||
fn ->
|
||||
defposts do
|
||||
actions do
|
||||
|
@ -62,7 +62,7 @@ defmodule Ash.Test.Dsl.Resource.Actions.UpdateTest do
|
|||
test "it fails if `rules` is not a list" do
|
||||
assert_raise(
|
||||
Ash.Error.ResourceDslError,
|
||||
"option rules at actions -> update -> default must be of type {:list, {:struct, Ash.Authorization.Rule}}",
|
||||
"option rules at actions -> update -> default must be [{:struct, Ash.Authorization.Rule}]",
|
||||
fn ->
|
||||
defposts do
|
||||
actions do
|
||||
|
@ -76,7 +76,7 @@ defmodule Ash.Test.Dsl.Resource.Actions.UpdateTest do
|
|||
test "it fails if the elements of the rules list are not rules" do
|
||||
assert_raise(
|
||||
Ash.Error.ResourceDslError,
|
||||
"option rules at actions -> update -> default must be of type {:list, {:struct, Ash.Authorization.Rule}}",
|
||||
"option rules at actions -> update -> default must be [{:struct, Ash.Authorization.Rule}]",
|
||||
fn ->
|
||||
defposts do
|
||||
actions do
|
||||
|
|
|
@ -56,7 +56,7 @@ defmodule Ash.Test.Resource.AttributesTest do
|
|||
test "raises if you pass an invalid value for `primary_key?`" do
|
||||
assert_raise(
|
||||
Ash.Error.ResourceDslError,
|
||||
"option primary_key? at attributes -> attribute must be of type :boolean",
|
||||
"option primary_key? at attributes -> attribute must be boolean",
|
||||
fn ->
|
||||
defposts do
|
||||
attributes do
|
||||
|
|
|
@ -55,7 +55,7 @@ defmodule Ash.Test.Resource.Relationships.BelongsToTest do
|
|||
test "fails if destination_field is not an atom" do
|
||||
assert_raise(
|
||||
Ash.Error.ResourceDslError,
|
||||
"option destination_field at relationships -> belongs_to -> foobar must be of type :atom",
|
||||
"option destination_field at relationships -> belongs_to -> foobar must be atom",
|
||||
fn ->
|
||||
defposts do
|
||||
relationships do
|
||||
|
@ -69,7 +69,7 @@ defmodule Ash.Test.Resource.Relationships.BelongsToTest do
|
|||
test "fails if source_field is not an atom" do
|
||||
assert_raise(
|
||||
Ash.Error.ResourceDslError,
|
||||
"option source_field at relationships -> belongs_to -> foobar must be of type :atom",
|
||||
"option source_field at relationships -> belongs_to -> foobar must be atom",
|
||||
fn ->
|
||||
defposts do
|
||||
relationships do
|
||||
|
@ -111,7 +111,7 @@ defmodule Ash.Test.Resource.Relationships.BelongsToTest do
|
|||
test "fails if `primary_key?` is not a boolean" do
|
||||
assert_raise(
|
||||
Ash.Error.ResourceDslError,
|
||||
"option primary_key? at relationships -> belongs_to -> foobar must be of type :boolean",
|
||||
"option primary_key? at relationships -> belongs_to -> foobar must be boolean",
|
||||
fn ->
|
||||
defposts do
|
||||
relationships do
|
||||
|
@ -126,7 +126,7 @@ defmodule Ash.Test.Resource.Relationships.BelongsToTest do
|
|||
test "fails if `define_field?` is not a boolean" do
|
||||
assert_raise(
|
||||
Ash.Error.ResourceDslError,
|
||||
"option define_field? at relationships -> belongs_to -> foobar must be of type :boolean",
|
||||
"option define_field? at relationships -> belongs_to -> foobar must be boolean",
|
||||
fn ->
|
||||
defposts do
|
||||
relationships do
|
||||
|
@ -140,7 +140,7 @@ defmodule Ash.Test.Resource.Relationships.BelongsToTest do
|
|||
test "fails if `field_type` is not an atom" do
|
||||
assert_raise(
|
||||
Ash.Error.ResourceDslError,
|
||||
"option field_type at relationships -> belongs_to -> foobar must be of type :atom",
|
||||
"option field_type at relationships -> belongs_to -> foobar must be atom",
|
||||
fn ->
|
||||
defposts do
|
||||
relationships do
|
||||
|
|
|
@ -36,7 +36,7 @@ defmodule Ash.Test.Resource.Relationshihps.HasManyTest do
|
|||
test "fails if destination_field is not an atom" do
|
||||
assert_raise(
|
||||
Ash.Error.ResourceDslError,
|
||||
"option destination_field at relationships -> has_many -> foobar must be of type :atom",
|
||||
"option destination_field at relationships -> has_many -> foobar must be atom",
|
||||
fn ->
|
||||
defposts do
|
||||
relationships do
|
||||
|
@ -50,7 +50,7 @@ defmodule Ash.Test.Resource.Relationshihps.HasManyTest do
|
|||
test "fails if source_field is not an atom" do
|
||||
assert_raise(
|
||||
Ash.Error.ResourceDslError,
|
||||
"option source_field at relationships -> has_many -> foobar must be of type :atom",
|
||||
"option source_field at relationships -> has_many -> foobar must be atom",
|
||||
fn ->
|
||||
defposts do
|
||||
relationships do
|
||||
|
|
|
@ -36,7 +36,7 @@ defmodule Ash.Test.Resource.Relationshihps.HasOneTest do
|
|||
test "fails if destination_field is not an atom" do
|
||||
assert_raise(
|
||||
Ash.Error.ResourceDslError,
|
||||
"option destination_field at relationships -> has_one -> foobar must be of type :atom",
|
||||
"option destination_field at relationships -> has_one -> foobar must be atom",
|
||||
fn ->
|
||||
defposts do
|
||||
relationships do
|
||||
|
@ -50,7 +50,7 @@ defmodule Ash.Test.Resource.Relationshihps.HasOneTest do
|
|||
test "fails if source_field is not an atom" do
|
||||
assert_raise(
|
||||
Ash.Error.ResourceDslError,
|
||||
"option source_field at relationships -> has_one -> foobar must be of type :atom",
|
||||
"option source_field at relationships -> has_one -> foobar must be atom",
|
||||
fn ->
|
||||
defposts do
|
||||
relationships do
|
||||
|
|
|
@ -55,7 +55,7 @@ defmodule Ash.Test.Resource.Relationships.ManyToManyTest do
|
|||
test "it fails if you dont pass an atom for `source_field_on_join_table`" do
|
||||
assert_raise(
|
||||
Ash.Error.ResourceDslError,
|
||||
"option source_field_on_join_table at relationships -> many_to_many -> foobars must be of type :atom",
|
||||
"option source_field_on_join_table at relationships -> many_to_many -> foobars must be atom",
|
||||
fn ->
|
||||
defposts do
|
||||
relationships do
|
||||
|
@ -69,7 +69,7 @@ defmodule Ash.Test.Resource.Relationships.ManyToManyTest do
|
|||
test "it fails if you dont pass an atom for `destination_field_on_join_table`" do
|
||||
assert_raise(
|
||||
Ash.Error.ResourceDslError,
|
||||
"option destination_field_on_join_table at relationships -> many_to_many -> foobars must be of type :atom",
|
||||
"option destination_field_on_join_table at relationships -> many_to_many -> foobars must be atom",
|
||||
fn ->
|
||||
defposts do
|
||||
relationships do
|
||||
|
@ -85,7 +85,7 @@ defmodule Ash.Test.Resource.Relationships.ManyToManyTest do
|
|||
test "it fails if you dont pass an atom for `source_field`" do
|
||||
assert_raise(
|
||||
Ash.Error.ResourceDslError,
|
||||
"option source_field at relationships -> many_to_many -> foobars must be of type :atom",
|
||||
"option source_field at relationships -> many_to_many -> foobars must be atom",
|
||||
fn ->
|
||||
defposts do
|
||||
relationships do
|
||||
|
@ -101,7 +101,7 @@ defmodule Ash.Test.Resource.Relationships.ManyToManyTest do
|
|||
test "it fails if you dont pass an atom for `destination_field`" do
|
||||
assert_raise(
|
||||
Ash.Error.ResourceDslError,
|
||||
"option destination_field at relationships -> many_to_many -> foobars must be of type :atom",
|
||||
"option destination_field at relationships -> many_to_many -> foobars must be atom",
|
||||
fn ->
|
||||
defposts do
|
||||
relationships do
|
||||
|
|
Loading…
Reference in a new issue