diff --git a/lib/ash/resource.ex b/lib/ash/resource.ex index 596a2d97..52a74a97 100644 --- a/lib/ash/resource.ex +++ b/lib/ash/resource.ex @@ -1,26 +1,9 @@ defmodule Ash.Resource do - @resource_opts_schema [ - name: [ - type: :string, - required: true, - doc: - "The name of the resource, e.g `posts` or `authors`. This will typically be the pluralized form of the type" - ], - type: [ - type: :string, - required: true, - doc: "The type of the resource, e.g `post` or `author`. This is used throughout the system." - ] - ] - @moduledoc """ A resource is a static definition of an entity in your system. Resource DSL documentation: `Ash.Resource.DSL` - The following options apply to `use Ash.Resource, [...]` - #{NimbleOptions.docs(@resource_opts_schema)} - For more information on the resource DSL, see `Ash.Resource.DSL` Note: @@ -28,10 +11,6 @@ defmodule Ash.Resource do API and can change at any time. Instead, use the `Ash` module, for example: `Ash.type(MyResource)` """ - @doc "The name of the resource, e.g 'posts'" - @callback name() :: String.t() - @doc "The type of the resource, e.g 'post'" - @callback type() :: String.t() @doc "A list of attribute names that make up the primary key, e.g [:class, :group]" @callback primary_key() :: [atom] @doc "A list of relationships to other resources" @@ -49,30 +28,19 @@ defmodule Ash.Resource do @doc "A list of authorizers to be used when accessing the resource" @callback authorizers() :: [module] - defmacro __using__(opts) do + defmacro __using__(_opts) do quote do @before_compile Ash.Resource @behaviour Ash.Resource - opts = - case NimbleOptions.validate(unquote(opts), Ash.Resource.resource_opts_schema()) do - {:error, message} -> - raise Ash.Error.ResourceDslError, - using: __MODULE__, - message: message - - {:ok, opts} -> - opts - end - - Ash.Resource.define_resource_module_attributes(__MODULE__, opts) + Ash.Resource.define_resource_module_attributes(__MODULE__) use Ash.Resource.DSL end end @doc false - def define_resource_module_attributes(mod, opts) do + def define_resource_module_attributes(mod) do Module.register_attribute(mod, :before_compile_hooks, accumulate: true) Module.register_attribute(mod, :actions, accumulate: true) Module.register_attribute(mod, :attributes, accumulate: true) @@ -80,17 +48,10 @@ defmodule Ash.Resource do Module.register_attribute(mod, :extensions, accumulate: true) Module.register_attribute(mod, :authorizers, accumulate: true) - Module.put_attribute(mod, :name, opts[:name]) - Module.put_attribute(mod, :resource_type, opts[:type]) Module.put_attribute(mod, :data_layer, nil) Module.put_attribute(mod, :description, nil) end - @doc false - def resource_opts_schema do - @resource_opts_schema - end - # credo:disable-for-next-line Credo.Check.Refactor.CyclomaticComplexity defmacro __before_compile__(env) do quote do @@ -115,11 +76,7 @@ defmodule Ash.Resource do require Ash.Schema - Ash.Schema.define_schema(@name) - - def type do - @resource_type - end + Ash.Schema.define_schema() def relationships do @relationships @@ -137,10 +94,6 @@ defmodule Ash.Resource do @ash_primary_key end - def name do - @name - end - def extensions do @extensions end diff --git a/lib/ash/resource/relationships/has_many.ex b/lib/ash/resource/relationships/has_many.ex index d7ff15fa..d4854782 100644 --- a/lib/ash/resource/relationships/has_many.ex +++ b/lib/ash/resource/relationships/has_many.ex @@ -26,6 +26,7 @@ defmodule Ash.Resource.Relationships.HasMany do @opt_schema [ destination_field: [ type: :atom, + required: true, doc: "The field on the related resource that should match the `source_field` on this resource. Default: [resource.name]_id" ], @@ -52,7 +53,7 @@ defmodule Ash.Resource.Relationships.HasMany do opts :: Keyword.t() ) :: {:ok, t()} | {:error, term} # sobelow_skip ["DOS.BinToAtom"] - def new(resource, resource_type, name, related_resource, opts \\ []) do + def new(resource, name, related_resource, opts \\ []) do # Don't call functions on the resource! We don't want it to compile here case NimbleOptions.validate(opts, @opt_schema) do {:ok, opts} -> @@ -63,7 +64,7 @@ defmodule Ash.Resource.Relationships.HasMany do type: :has_many, cardinality: :many, destination: related_resource, - destination_field: opts[:destination_field] || :"#{resource_type}_id", + destination_field: opts[:destination_field], source_field: opts[:source_field], reverse_relationship: opts[:reverse_relationship] }} diff --git a/lib/ash/resource/relationships/has_one.ex b/lib/ash/resource/relationships/has_one.ex index 7b9f3a51..1e21b5b7 100644 --- a/lib/ash/resource/relationships/has_one.ex +++ b/lib/ash/resource/relationships/has_one.ex @@ -29,6 +29,7 @@ defmodule Ash.Resource.Relationships.HasOne do @opt_schema [ destination_field: [ type: :atom, + required: true, doc: "The field on the related resource that should match the `source_field` on this resource. Default: [resource.name]_id" ], @@ -50,13 +51,12 @@ defmodule Ash.Resource.Relationships.HasOne do @spec new( resource :: Ash.resource(), - resource_type :: String.t(), name :: atom, related_resource :: Ash.resource(), opts :: Keyword.t() ) :: {:ok, t()} | {:error, term} # sobelow_skip ["DOS.BinToAtom"] - def new(resource, resource_type, name, related_resource, opts \\ []) do + def new(resource, name, related_resource, opts \\ []) do # Don't call functions on the resource! We don't want it to compile here case NimbleOptions.validate(opts, @opt_schema) do {:ok, opts} -> @@ -67,7 +67,7 @@ defmodule Ash.Resource.Relationships.HasOne do type: :has_one, cardinality: :one, destination: related_resource, - destination_field: opts[:destination_field] || :"#{resource_type}_id", + destination_field: opts[:destination_field], source_field: opts[:source_field], reverse_relationship: opts[:reverse_relationship] }} diff --git a/lib/ash/resource/relationships/many_to_many.ex b/lib/ash/resource/relationships/many_to_many.ex index 23eb0653..c14c5d11 100644 --- a/lib/ash/resource/relationships/many_to_many.ex +++ b/lib/ash/resource/relationships/many_to_many.ex @@ -31,6 +31,7 @@ defmodule Ash.Resource.Relationships.ManyToMany do @opt_schema [ source_field_on_join_table: [ type: :atom, + required: true, doc: "The field on the join table that should line up with `source_field` on this resource. Default: [resource_name]_id" ], @@ -68,13 +69,12 @@ defmodule Ash.Resource.Relationships.ManyToMany do @spec new( resource :: Ash.resource(), - resource_name :: String.t(), name :: atom, related_resource :: Ash.resource(), opts :: Keyword.t() ) :: {:ok, t()} | {:error, term} # sobelow_skip ["DOS.BinToAtom"] - def new(resource, resource_name, name, related_resource, opts \\ []) do + def new(resource, name, related_resource, opts \\ []) do # Don't call functions on the resource! We don't want it to compile here case NimbleOptions.validate(opts, @opt_schema) do {:ok, opts} -> @@ -89,8 +89,7 @@ defmodule Ash.Resource.Relationships.ManyToMany do reverse_relationship: opts[:reverse_relationship], source_field: opts[:source_field], destination_field: opts[:destination_field], - source_field_on_join_table: - opts[:source_field_on_join_table] || :"#{resource_name}_id", + source_field_on_join_table: opts[:source_field_on_join_table], destination_field_on_join_table: opts[:destination_field_on_join_table] || :"#{name}_id" }} diff --git a/lib/ash/resource/relationships/relationships.ex b/lib/ash/resource/relationships/relationships.ex index 36e768b8..4cc8ac69 100644 --- a/lib/ash/resource/relationships/relationships.ex +++ b/lib/ash/resource/relationships/relationships.ex @@ -77,7 +77,6 @@ defmodule Ash.Resource.Relationships do relationship = HasOne.new( __MODULE__, - @resource_type, relationship_name, destination, opts @@ -251,7 +250,6 @@ defmodule Ash.Resource.Relationships do relationship = Relationships.HasMany.new( __MODULE__, - @resource_type, relationship_name, destination, opts @@ -319,7 +317,6 @@ defmodule Ash.Resource.Relationships do many_to_many = Relationships.ManyToMany.new( __MODULE__, - @name, relationship_name, destination, opts @@ -330,7 +327,6 @@ defmodule Ash.Resource.Relationships do has_many = Relationships.HasMany.new( __MODULE__, - @name, has_many_name, opts[:through], destination_field: opts[:source_field_on_join_table], diff --git a/lib/ash/resource/schema.ex b/lib/ash/resource/schema.ex index 5cda223e..a7babfb7 100644 --- a/lib/ash/resource/schema.ex +++ b/lib/ash/resource/schema.ex @@ -6,12 +6,12 @@ defmodule Ash.Schema do # This defines struct representation of a resource. Data layers can rely on this # schema for persistence. - defmacro define_schema(name) do + defmacro define_schema do quote do use Ecto.Schema @primary_key false - schema unquote(name) do + schema "" do for attribute <- @attributes do read_after_writes? = attribute.generated? and is_nil(attribute.default)