\ ឵឵឵
\ ឵឵឵
AEAsh Elixir
Created by \ ឵឵឵ on 6/29/2023 in #support
Hooking `manage_relationship`
Is there a way to specifically hook into manage_relationship, e.g. for an extension? I'm looking to get notified any time a relationship is added or removed.
10 replies
AEAsh Elixir
Created by \ ឵឵឵ on 6/14/2023 in #support
Simulating arguments on relationships with calculations
I've seen questions related to this come up in various forms pretty regularly over the last few months, and given the outcome of https://github.com/ash-project/ash/issues/375, I thought it might be helpful to collect a series of examples for common patterns in simulating parameterized relationships with calculations. Happy to turn the output of this into a patch to the docs for a new guide, or new section of the Calculations guide.
4 replies
AEAsh Elixir
Created by \ ឵឵឵ on 6/2/2023 in #showcase
AshGeo: Tools for using Geo, Topo and PostGIS
I've noticed some chatter on here from folks working with geospatial, and decided to pull something out from under my umbrella: ash_geo. It provides: - All the st_* functions that you would get with Geo.PostGIS for use with Ash expr, and more to come - An Ash.Type backed by each of Geo.JSON, Geo.WKB and Geo.WKT which may be used as argument types in your Ash actions, and will automatically cast input from GeoJSON, WKT and WKB encodings - An Ash.Type for Geo.PostGIS.Geometry, for use with resource attributes - All types may be overridden and narrowed with use, allowing you to add stricter constraints and storage types (e.g. geometry(Point,26918)). - Validations for Geo types (such as is_point_zm(:arg) for checking that argument :arg is a instance of Geo.PointZM) - Validations backed by Topo, allowing checks of simple constraints such as contains? without needing to hit the database v0.1.0 is released on Hex. Ideas and thoughts welcome! Feel free to open issues/PRs and to reply to this thread 🙂 Much love to the Ash community ♥️ Hoping it comes in handy. https://github.com/bcksl/ash_geo
7 replies
AEAsh Elixir
Created by \ ឵឵឵ on 5/27/2023 in #support
Ideal location for pivots across APIs
Another one of my registries has grown fairly large and I'm considering a split. The registry is highly connected, and has a lot of many_to_many relationships. Beyond a matter of preference, anything to be aware of when deciding which of the split APIs a given join resource should live? Should cross-API joins work regardless as long as the APIs are on the same repo?
5 replies
AEAsh Elixir
Created by \ ឵឵឵ on 5/25/2023 in #support
Absinthe compilation error
Any ideas what might be triggering this?
== Compilation error in file lib/app/schema.ex ==
** (KeyError) key :location not found in: nil. If you are using the dot syntax, such as map.field, make sure the left-hand side of the dot is a map
(absinthe 1.7.1) lib/absinthe/phase/schema/validation/type_references_exist.ex:142: Absinthe.Phase.Schema.Validation.TypeReferencesExist.error/2
(absinthe 1.7.1) lib/absinthe/phase/schema/validation/type_references_exist.ex:114: Absinthe.Phase.Schema.Validation.TypeReferencesExist.check_or_error/4
(absinthe 1.7.1) lib/absinthe/blueprint/transform.ex:16: anonymous fn/3 in Absinthe.Blueprint.Transform.prewalk/2
(absinthe 1.7.1) lib/absinthe/blueprint/transform.ex:117: Absinthe.Blueprint.Transform.walk/4
(elixir 1.14.5) lib/enum.ex:1780: Enum."-map_reduce/3-lists^mapfoldl/2-0-"/3
(absinthe 1.7.1) lib/absinthe/blueprint/transform.ex:147: anonymous fn/4 in Absinthe.Blueprint.Transform.walk_children/5
(elixir 1.14.5) lib/enum.ex:2468: Enum."-reduce/3-lists^foldl/2-0-"/3
(absinthe 1.7.1) lib/absinthe/blueprint/transform.ex:122: Absinthe.Blueprint.Transform.walk/4
make: *** [build] Error 1
== Compilation error in file lib/app/schema.ex ==
** (KeyError) key :location not found in: nil. If you are using the dot syntax, such as map.field, make sure the left-hand side of the dot is a map
(absinthe 1.7.1) lib/absinthe/phase/schema/validation/type_references_exist.ex:142: Absinthe.Phase.Schema.Validation.TypeReferencesExist.error/2
(absinthe 1.7.1) lib/absinthe/phase/schema/validation/type_references_exist.ex:114: Absinthe.Phase.Schema.Validation.TypeReferencesExist.check_or_error/4
(absinthe 1.7.1) lib/absinthe/blueprint/transform.ex:16: anonymous fn/3 in Absinthe.Blueprint.Transform.prewalk/2
(absinthe 1.7.1) lib/absinthe/blueprint/transform.ex:117: Absinthe.Blueprint.Transform.walk/4
(elixir 1.14.5) lib/enum.ex:1780: Enum."-map_reduce/3-lists^mapfoldl/2-0-"/3
(absinthe 1.7.1) lib/absinthe/blueprint/transform.ex:147: anonymous fn/4 in Absinthe.Blueprint.Transform.walk_children/5
(elixir 1.14.5) lib/enum.ex:2468: Enum."-reduce/3-lists^foldl/2-0-"/3
(absinthe 1.7.1) lib/absinthe/blueprint/transform.ex:122: Absinthe.Blueprint.Transform.walk/4
make: *** [build] Error 1
8 replies
AEAsh Elixir
Created by \ ឵឵឵ on 5/24/2023 in #support
`Spark` templates
I have a number of resource templates that are defined as __using__ macros, primarily for the sake of ergonomics and readability. As some of these have begun to solidify, I have converted them to Spark extensions. What I'm wondering is if we can have the best of both worlds. For example, by allowing extensions to provide a Spark options schema and selecting a syntax to walk in Spark.Dsl.Fragment (or a new Spark.Dsl.Template) in order to inject options into the fragment/template. This would be even more interesting if extensions were able to inject other extensions with options taken from their own DSL, but this may be a harder hill to climb. Would the compile-time checks and error reporting be worth the effort? Any big impediments to allowing extensions to take options, even without necessitating them being specified in the DSL? Is this already possible? 😄 A very boring example:
defmodule App.Template.StringAttr do
use Spark.Dsl.Template, for: Ash.Resource

attributes do
attribute @@attribute, :string, @@attribute_opts
end
end
defmodule App.Template.StringAttr do
use Spark.Dsl.Template, for: Ash.Resource

attributes do
attribute @@attribute, :string, @@attribute_opts
end
end
defmodule App.Resource.Named do
use Ash.Resource, templates: [
{App.Template.StringAttr, attribute: :name}
end
defmodule App.Resource.Named do
use Ash.Resource, templates: [
{App.Template.StringAttr, attribute: :name}
end
Related: https://discord.com/channels/711271361523351632/1019647368196534283/threads/1110677874198986852: re: a callback to allow extensions to add other extensions
14 replies
AEAsh Elixir
Created by \ ឵឵឵ on 5/23/2023 in #support
Can an extension add a notifier/fragment?
Quick poke leads me to believe this is the same as asking whether an extension can add other extensions, since notifiers and fragments are just special kinds of extensions.
30 replies
AEAsh Elixir
Created by \ ឵឵឵ on 5/22/2023 in #support
Annotating manual actions and custom changes for policies
My current understanding is that policy builtins like changing and selecting won't see into manual actions at all, and that they will see into custom changes to the degree expressed by the returned changeset and not further. In the case that one requires a manual action, or to overcome any limitations for custom changes, is it possible to annotate the action, indicating to Ash that the manual is going to affect certain attributes or otherwise do things that a policy might care about?
43 replies
AEAsh Elixir
Created by \ ឵឵឵ on 5/15/2023 in #support
`Spark.Dsl.Fragment` validations
It seems that when using Spark.Dsl.Fragment, there are some validations that are happening on the fragment which would be preferable to have happen on the complete resource. A couple examples: If I define my code_interface section in a separate file from the actions themselves, the validation fails something like:
The interface of App.Post refers to a non-existent action create
The interface of App.Post refers to a non-existent action create
The graphql section doesn't seem to suffer from this particular issue, allowing me to define list, get, etc. connectors to actions not defined in the fragment, but isn't happy if I define my type :"..." outside of the fragment, in this case as a transformer of my base resource. Perhaps the difference between these two has something to do with code_interface's more direct use of a transformer, v. graphql which parses the DSL primarily afterwards as part of the schema macro. Nonetheless, is there something stopping us from having Spark.Dsl.Fragments—or something similar—assembled into a complete resource before any transformers/validations are run?
4 replies
AEAsh Elixir
Created by \ ឵឵឵ on 5/7/2023 in #support
`bulk_create` requiring `upsert_fields` with `upsert?: true`
Small conflict between the docs and usage of bulk_create: Docs: "If not set, the action's upsert_fields is used, and if that is not set, then any fields not being set to defaults are written." https://hexdocs.pm/ash/Ash.Api.html#c:bulk_create/4 The error:
** (ArgumentError) For bulk actions, `upsert_fields` must be specified if upsert? is set to true`
** (ArgumentError) For bulk actions, `upsert_fields` must be specified if upsert? is set to true`
7 replies
AEAsh Elixir
Created by \ ឵឵឵ on 5/4/2023 in #support
Adding macros to `expr/1`
I'd like to add the st_* macros from GeoPostGIS to expr/1, possibly more in future. These macros do generate exactly the fragment syntax that is currently supported by expr, which is pretty nice, but they don't work as-is. Is doesn't look like it's possible currently to extend Ash.Expr, and I'm quite interested in changing that, or at least making it possible to mix in external macros in this way using the existing supporting constructs like fragment. Has there been any interest/thought up to now on this topic? https://github.com/bryanjos/geo_postgis/blob/master/lib/geo_postgis.ex
68 replies
AEAsh Elixir
Created by \ ឵឵឵ on 5/1/2023 in #support
Splitting resource using AshStateMachine using `Spark.Dsl.Fragment`
What I was hoping to do was be able to split my state_machine block from the rest of the resource using Spark.Dsl.Fragment. Bit of a catch-22 though, because without using the AshStateMachine extension there's notransition_state to use in actions, but with it there's no definition for initial_states. This hasn't been an issue for anything else, because for other extensions like AshGraphql, AshJsonApi, etc. there aren't the same kind of interdependencies and the rest of the stuff doesn't seem to get hung up because it's all in core. Is this a case worth addressing somehow? I can see there being more extensions in future that would, e.g. similarly provide additional changes builtins, but also have their own DSL section large enough to want to split it.
11 replies
AEAsh Elixir
Created by \ ឵឵឵ on 4/30/2023 in #support
Filtering relationships in `relates_to_actor_via` etc.
Have a number of cases that I'm looking to set up policies and/or filters that perform a deep (but simple) join where for some path components it's necessary to filter the relationship. It's not feasible to create a different relationship for each possible filter, and I wanted to make sure that for right now I'm looking at doing the join manually in a custom check/filter. Generally would be interested in the current thought process for supporting parameterized relationships, and whether this is one of the target scenarios that's intended to be addressed. Related: - https://github.com/orgs/ash-project/projects/3?pane=issue&itemId=10193112
13 replies
AEAsh Elixir
Created by \ ឵឵឵ on 4/26/2023 in #support
Limiting action sort and filter
I'm going through and starting to audit my setup for sorting and filtering. Ideally, it would only be possible to sort and filter on a limited set of attributes/relationships. I can block anything I don't want with filtering_on policies, but I'd like to get it out of my GraphQL schema and JSON:API altogether. Is there a way to define at the action and/or resource level which attributes and relationships are allowed to be sorted and filtered on? If there is a way to do this, is there also a flag that would set these to [] by default globally? I'd prefer to explicitly allow rather than deny. This seems to be in-line with the planned changes for Ash 3.0, re: accept defaulting to [].
91 replies
AEAsh Elixir
Created by \ ឵឵឵ on 4/26/2023 in #support
Shorthand for code interface filters
Is there a handy shortcut for doing something like:
use Ash.Expr

Post.read! expr(title == "Nice")
use Ash.Expr

Post.read! expr(title == "Nice")
2 replies
AEAsh Elixir
Created by \ ឵឵឵ on 4/24/2023 in #support
Singleton resources
Singleton being defined as: "There is only ever one, no more and no less." Is there a recommended pattern? So far I have something that is basically anAsh.Resource with create, read and update actions and: - Does not allow anybody to call create, and does not expose it via frontend channels; - Automatically populates the record if it does not exist with the bare create using authorize?: false; - Automatically fetches the single record using in update. This is somewhat less than ideal. Would there be interest in supporting something like this more explicitly? The primary difference in behaviour to other resource types are: - They cannot be created or destroyed. - They can only be read or updated. - It is unnecessary to pass an instance of them to update actions. - There is no sense in filtering them (but still sense in determining which attributes to select). Otherwise, many of the same things that make sense for other types of resources make sense for singletons as well, and there are a fair number of situations where the thing that best describes my domain is a singleton.
11 replies
AEAsh Elixir
Created by \ ឵឵឵ on 4/22/2023 in #support
AshStateMachine transitions from/to multiple states and no default initial state
Is there a way I can pass an array to from: and to:? Right now for the latter case it only makes sense if I can explicitly pass the state to transition to in the change builtin. Can I not specify a default initial state, and simply require that it be one of a set of initial states and not be nil? Tagging this Core for now.
151 replies
AEAsh Elixir
Created by \ ឵឵឵ on 4/20/2023 in #support
Migration generator splitting composite primary keys
Before, I believe the recommendation was to do many_to_many relationships like so:
relationships do
belongs_to :resource_a, App.ResourceA, primary_key?: true, allow_nil?: false
belongs_to :resource_b, App.ResourceB, primary_key?: true, allow_nil?: false
end
relationships do
belongs_to :resource_a, App.ResourceA, primary_key?: true, allow_nil?: false
belongs_to :resource_b, App.ResourceB, primary_key?: true, allow_nil?: false
end
But now this results in:
** (Postgrex.Error) ERROR 42P16 (invalid_table_definition) multiple primary keys for table "resourcea_resourceb" are not allowed
(ecto_sql 3.10.1) lib/ecto/adapters/sql.ex:913: Ecto.Adapters.SQL.raise_sql_call_error/1
(elixir 1.14.4) lib/enum.ex:1658: Enum."-map/2-lists^map/1-0-"/2
(ecto_sql 3.10.1) lib/ecto/adapters/sql.ex:1005: Ecto.Adapters.SQL.execute_ddl/4
(ecto_sql 3.10.1) lib/ecto/migration/runner.ex:327: Ecto.Migration.Runner.log_and_execute_ddl/3
(ecto_sql 3.10.1) lib/ecto/migration/runner.ex:117: anonymous fn/6 in Ecto.Migration.Runner.flush/0
(elixir 1.14.4) lib/enum.ex:2468: Enum."-reduce/3-lists^foldl/2-0-"/3
(ecto_sql 3.10.1) lib/ecto/migration/runner.ex:116: Ecto.Migration.Runner.flush/0
(ecto_sql 3.10.1) lib/ecto/migration/runner.ex:290: Ecto.Migration.Runner.perform_operation/3
make: *** [db-migrate] Error 1
** (Postgrex.Error) ERROR 42P16 (invalid_table_definition) multiple primary keys for table "resourcea_resourceb" are not allowed
(ecto_sql 3.10.1) lib/ecto/adapters/sql.ex:913: Ecto.Adapters.SQL.raise_sql_call_error/1
(elixir 1.14.4) lib/enum.ex:1658: Enum."-map/2-lists^map/1-0-"/2
(ecto_sql 3.10.1) lib/ecto/adapters/sql.ex:1005: Ecto.Adapters.SQL.execute_ddl/4
(ecto_sql 3.10.1) lib/ecto/migration/runner.ex:327: Ecto.Migration.Runner.log_and_execute_ddl/3
(ecto_sql 3.10.1) lib/ecto/migration/runner.ex:117: anonymous fn/6 in Ecto.Migration.Runner.flush/0
(elixir 1.14.4) lib/enum.ex:2468: Enum."-reduce/3-lists^foldl/2-0-"/3
(ecto_sql 3.10.1) lib/ecto/migration/runner.ex:116: Ecto.Migration.Runner.flush/0
(ecto_sql 3.10.1) lib/ecto/migration/runner.ex:290: Ecto.Migration.Runner.perform_operation/3
make: *** [db-migrate] Error 1
I can confirm that it is splitting these into two separate add ... primary_key: true statements in the migrations, just spotted due to regenerating. Is there a different approach now, or is this a bug?
5 replies
AEAsh Elixir
Created by \ ឵឵឵ on 4/19/2023 in #support
`mix ash_postgres.generate_migrations` key `:table` not found
mix ash_postgres.generate_migrations

Extension Migrations:
No extensions to install

Generating Tenant Migrations:

Generating Migrations:
** (KeyError) key :table not found in: nil. If you are using the dot syntax, such as map.field, make sure the left-hand side of the dot is a map
(ash_postgres 1.3.19) lib/migration_generator/migration_generator.ex:127: anonymous fn/2 in AshPostgres.MigrationGenerator.find_references_primary_key/2
(elixir 1.14.4) lib/enum.ex:4239: Enum.find_value_list/3
(ash_postgres 1.3.19) lib/migration_generator/migration_generator.ex:109: anonymous fn/2 in AshPostgres.MigrationGenerator.add_references_primary_key/2
(elixir 1.14.4) lib/enum.ex:1658: Enum."-map/2-lists^map/1-0-"/2
(elixir 1.14.4) lib/enum.ex:1658: Enum."-map/2-lists^map/1-0-"/2
(ash_postgres 1.3.19) lib/migration_generator/migration_generator.ex:100: AshPostgres.MigrationGenerator.add_references_primary_key/2
(ash_postgres 1.3.19) lib/migration_generator/migration_generator.ex:503: anonymous fn/2 in AshPostgres.MigrationGenerator.deduplicate_snapshots/4
(elixir 1.14.4) lib/map.ex:258: Map.do_map/2
make: *** [migrations] Error 1
mix ash_postgres.generate_migrations

Extension Migrations:
No extensions to install

Generating Tenant Migrations:

Generating Migrations:
** (KeyError) key :table not found in: nil. If you are using the dot syntax, such as map.field, make sure the left-hand side of the dot is a map
(ash_postgres 1.3.19) lib/migration_generator/migration_generator.ex:127: anonymous fn/2 in AshPostgres.MigrationGenerator.find_references_primary_key/2
(elixir 1.14.4) lib/enum.ex:4239: Enum.find_value_list/3
(ash_postgres 1.3.19) lib/migration_generator/migration_generator.ex:109: anonymous fn/2 in AshPostgres.MigrationGenerator.add_references_primary_key/2
(elixir 1.14.4) lib/enum.ex:1658: Enum."-map/2-lists^map/1-0-"/2
(elixir 1.14.4) lib/enum.ex:1658: Enum."-map/2-lists^map/1-0-"/2
(ash_postgres 1.3.19) lib/migration_generator/migration_generator.ex:100: AshPostgres.MigrationGenerator.add_references_primary_key/2
(ash_postgres 1.3.19) lib/migration_generator/migration_generator.ex:503: anonymous fn/2 in AshPostgres.MigrationGenerator.deduplicate_snapshots/4
(elixir 1.14.4) lib/map.ex:258: Map.do_map/2
make: *** [migrations] Error 1
10 replies
AEAsh Elixir
Created by \ ឵឵឵ on 4/18/2023 in #support
`AshGraphql.Error` not implemented
Looks like a policy error is being raised and not caught somewhere:
[warning] `fb1756e7-6a42-43c1-a11c-9758d305ac78`: AshGraphql.Error not implemented for error:

** (ErlangError) Erlang error: {%Ash.Error.Forbidden{errors: [%Ash.Error.Forbidden.Policy{scenarios: [], facts: %{false => false, true => true...
[warning] `fb1756e7-6a42-43c1-a11c-9758d305ac78`: AshGraphql.Error not implemented for error:

** (ErlangError) Erlang error: {%Ash.Error.Forbidden{errors: [%Ash.Error.Forbidden.Policy{scenarios: [], facts: %{false => false, true => true...
30 replies