AE
Ash Elixir•3y ago
axdc

No Such Relationship

I have a many_to_many relationship between Plan and Post. Plan is the source, the relationship is defined there. Post is the destination. PlansPosts is the join resource. It's all in the same api this time. I'm making a form with, and calling manage_relationship from, Post, and that's resulting in a Spark error:
** (EXIT from #PID<0.95.0>) an exception was raised:
** (Spark.Error.DslError) [Panacea.Sites.Post]
actions -> create -> commander_create -> change -> manage_relationship -> relate_plans -> plans:
No such relationship plans exists.
(ash 2.7.1) lib/ash/resource/transformers/validate_manage_relationship_opts.ex:40: anonymous fn/3 in Ash.Resource.Transformers.ValidateManagedRelationshipOpts.transform/1
** (EXIT from #PID<0.95.0>) an exception was raised:
** (Spark.Error.DslError) [Panacea.Sites.Post]
actions -> create -> commander_create -> change -> manage_relationship -> relate_plans -> plans:
No such relationship plans exists.
(ash 2.7.1) lib/ash/resource/transformers/validate_manage_relationship_opts.ex:40: anonymous fn/3 in Ash.Resource.Transformers.ValidateManagedRelationshipOpts.transform/1
I based this relationship on my existing, working, cross-api many_to_many SitesUsers, and I've run through the relationship guide a few more times to check if I'm missing anything from recent updates. Nothing is jumping out at me yet. Am I meant to be able to use relationships in actions on destination resources and not just source resources? That's the only difference that immediately comes to mind compared to the SitesUsers relationship that works. This error persists after mix clean --all, mix deps.update ash (still using main), etc
10 Replies
ZachDaniel
ZachDaniel•3y ago
🤔 manage_relationship(:plans) requires a :plans relationship. On the resource in question otherwise what would it be managing?
axdc
axdcOP•3y ago
Okay, so, right, currently I /think/ that relationship is being defined from the parent/source? Should I also define it in the destination which is where the action is? I may be misunderstanding how this is intended to work structurally plan.ex
relationships do
has_many :plans_posts, Panacea.Sites.PlansPosts

many_to_many :posts, Panacea.Sites.Post do
api Panacea.Sites
through(Panacea.Sites.PlansPosts)
source_attribute(:id)
source_attribute_on_join_resource(:plan_id)
destination_attribute(:id)
destination_attribute_on_join_resource(:post_id)
join_relationship :plans_posts
end
end
relationships do
has_many :plans_posts, Panacea.Sites.PlansPosts

many_to_many :posts, Panacea.Sites.Post do
api Panacea.Sites
through(Panacea.Sites.PlansPosts)
source_attribute(:id)
source_attribute_on_join_resource(:plan_id)
destination_attribute(:id)
destination_attribute_on_join_resource(:post_id)
join_relationship :plans_posts
end
end
post.ex
actions do
create :commander_create do
argument :relate_plans, {:array, :map} do
allow_nil? false
end

change manage_relationship(:relate_plans, :plans,
on_lookup: :relate,
on_no_match: :ignore,
on_missing: :unrelate,
on_match: :ignore
)
end
end
actions do
create :commander_create do
argument :relate_plans, {:array, :map} do
allow_nil? false
end

change manage_relationship(:relate_plans, :plans,
on_lookup: :relate,
on_no_match: :ignore,
on_missing: :unrelate,
on_match: :ignore
)
end
end
(correct me if i have committed a grave conceptual faux pas)
ZachDaniel
ZachDaniel•3y ago
Yeah, so you can only manage a relationship on the current resource So do you not have a :plans relationship on Post? Relationships are not bi-directional in this way. i.e one resource doesn't know that another relationship points at it so having a posts relationship on Plan wouldn't create a :plans relationship on Post (a good thing to ask there is how would we know to call it :plans?)
axdc
axdcOP•3y ago
Right. I defined the relationships on Plan because I was thinking it's intended to be a central source that many things hook into, like Site is, but whereas Site manages its child resources directly, you wouldn't go to the Plan area to manage posts or anything else that is sort of filtered by that plan clarifying my mental model So if I define a corresponding many_to_many on Post using the same join resource and everything, will that be okay with Spark? Or should I be rethinking the architecture?
ZachDaniel
ZachDaniel•3y ago
yeah that would be perfectly fine (in fact it is what typically happens for many to many relationships) Just make sure to flip your source_attribute_on_join_resource and destination_attribute_on_join_resource
axdc
axdcOP•3y ago
I considered this briefly and then assumed an inflector came into play 😅
ZachDaniel
ZachDaniel•3y ago
Gotcha, yeah we have enough magic without bringing wordplay into it 😆
axdc
axdcOP•3y ago
okay, NICE. i want to do what is typical and best practices etc, the golden path 😬
ZachDaniel
ZachDaniel•3y ago
Definitely standard to define relationships on both respective resources, but only if you need it for something so don't feel obligated to define every single relationship
axdc
axdcOP•3y ago
(cakephp brain) got it, I think i grok a little better what they're for now, ash is about explicit modeling, the relationships are needed on the resources that use them in their actions, there isn't an invisible handwavy land of bidirectional inference That's much more clear! Shallow water!

Did you find this page helpful?