Understanding value_is_key option when managing relationships

Given a relation that uses a ci_string (not uuid):
belongs_to :feature, Environments.Feature do
allow_nil? false
source_attribute :feature_key
attribute_type :ci_string
destination_attribute :key
end
belongs_to :feature, Environments.Feature do
allow_nil? false
source_attribute :feature_key
attribute_type :ci_string
destination_attribute :key
end
I would expect this change to work using value_is_key option:
argument :feature_key, :ci_string, allow_nil?: false
change manage_relationship(:feature_key, :feature,
type: :append,
value_is_key: :key,
use_identities: [:key]
)
argument :feature_key, :ci_string, allow_nil?: false
change manage_relationship(:feature_key, :feature,
type: :append,
value_is_key: :key,
use_identities: [:key]
)
But it gives me this error, but I thought the purpose of value_is_key is to not provide a struct:
** (Ash.Error.Invalid) Input Invalid
* Invalid value provided for feature: cannot provide structs that don't match the destination.
** (Ash.Error.Invalid) Input Invalid
* Invalid value provided for feature: cannot provide structs that don't match the destination.
For reference, this more verbose change does work:
argument :feature_key, :ci_string, allow_nil?: false

change fn changeset, _ ->
case Ash.Changeset.get_argument(changeset, :feature_key) do
nil ->
changeset

feature_key ->
Ash.Changeset.manage_relationship(
changeset,
:feature,
%{key: feature_key},
type: :append,
use_identities: [:key]
)
end
end
argument :feature_key, :ci_string, allow_nil?: false

change fn changeset, _ ->
case Ash.Changeset.get_argument(changeset, :feature_key) do
nil ->
changeset

feature_key ->
Ash.Changeset.manage_relationship(
changeset,
:feature,
%{key: feature_key},
type: :append,
use_identities: [:key]
)
end
end
9 Replies
ZachDaniel
ZachDaniel•2y ago
Ah, yep So what we need to do is check if that struct is a resource, and only raise that error then If you search for the error you could probably find the place to do this check And then check if Spark.Dsl.is?(module, Ash.Resource) If not, lets make an issue and I’ll take care of it tonight or tomorrow 🙂
Robert Graff
Robert GraffOP•2y ago
I could probably fix the code for my use case, but unsure if I could write proper tests and not break other use cases.
Robert Graff
Robert GraffOP•2y ago
GitHub
ash/lib/ash/changeset/changeset.ex at 216755b2759ded1ed24eab877f76a...
A declarative and extensible framework for building Elixir applications. - ash-project/ash
ZachDaniel
ZachDaniel•2y ago
yep! I'll fix it 😄
Robert Graff
Robert GraffOP•2y ago
GitHub
Ash.Changeset.manage_relationship raises Invalid Input when the ide...
Describe the bug Related to this discussion in discord, when using Ash.Changeset.manage_relationship an identity/key that is a :ci_string, the key is being validated because it is a struct and rais...
Robert Graff
Robert GraffOP•2y ago
Got this fix into my project a ran into a related issue. When the argument is a ci_string, I get an invalid error.
argument :plan_key, :ci_string, allow_nil?: false
change manage_relationship(:plan_key, :plan,
type: :append,
value_is_key: :key,
use_identities: [:key]
)

** (Ash.Error.Invalid) Input Invalid
* record with #Ash.CiString<"acme-widget-handle"> not found
argument :plan_key, :ci_string, allow_nil?: false
change manage_relationship(:plan_key, :plan,
type: :append,
value_is_key: :key,
use_identities: [:key]
)

** (Ash.Error.Invalid) Input Invalid
* record with #Ash.CiString<"acme-widget-handle"> not found
But a string argument will work
argument :plan_key, :string, allow_nil?: false

change manage_relationship(:plan_key, :plan,
type: :append,
value_is_key: :key,
use_identities: [:key]
)
argument :plan_key, :string, allow_nil?: false

change manage_relationship(:plan_key, :plan,
type: :append,
value_is_key: :key,
use_identities: [:key]
)
This is fine but unexpected
ZachDaniel
ZachDaniel•2y ago
🤔 interesting that doesn't really make sense... the ci_string should match any string the string matches. can I see the stacktrace?
Robert Graff
Robert GraffOP•2y ago
Let me dig into this and I'll get you a full trace. Since I had a work around, I've already shipped the branch. I'll get a new branch where I can reproduce soon. @Zach Daniel not much of a stacktrace. Any flags/configs to get more details?
1) test create/2 it should create with valid relationships (Kickplan.Organizations.AccountTest)
test/kickplan/environments/resources/account_test.exs:72
** (Ash.Error.Invalid) Input Invalid

* record with #Ash.CiString<"shields-schultz-and-gusikowski"> not found
code: Account.create!(
stacktrace:
(ash 2.11.10) lib/ash/api/api.ex:2167: Ash.Api.unwrap_or_raise!/3
test/kickplan/environments/resources/account_test.exs:88: (test)
1) test create/2 it should create with valid relationships (Kickplan.Organizations.AccountTest)
test/kickplan/environments/resources/account_test.exs:72
** (Ash.Error.Invalid) Input Invalid

* record with #Ash.CiString<"shields-schultz-and-gusikowski"> not found
code: Account.create!(
stacktrace:
(ash 2.11.10) lib/ash/api/api.ex:2167: Ash.Api.unwrap_or_raise!/3
test/kickplan/environments/resources/account_test.exs:88: (test)
ZachDaniel
ZachDaniel•2y ago
Looks like something missing in the error handling wherever that is

Did you find this page helpful?