AF
Ash Framework•4mo ago
Oliver

Using no attributes to use a parent_type / parent_id style table as a join table

I have this table:
attributes do
integer_primary_key :id

attribute :target_type, Safari.Types.LithostratTargetType, public?: true, allow_nil?: false
attribute :target_id, :integer, public?: true, allow_nil?: false
create_timestamp :inserted_at, public?: true
update_timestamp :updated_at, public?: true
end

relationships do
belongs_to :parent, Safari.Outcrop.Outcrop, public?: true, allow_nil?: false

has_one :group, Safari.Wiki.Group,
source_attribute: :target_id,
destination_attribute: :id,
filter: expr(parent(target_type) == :group)

has_one :formation, Safari.Wiki.Formation,
source_attribute: :target_id,
destination_attribute: :id,
filter: expr(parent(target_type) == :formation)

has_one :member, Safari.Wiki.Member,
source_attribute: :target_id,
destination_attribute: :id,
filter: expr(parent(target_type) == :member)
end
attributes do
integer_primary_key :id

attribute :target_type, Safari.Types.LithostratTargetType, public?: true, allow_nil?: false
attribute :target_id, :integer, public?: true, allow_nil?: false
create_timestamp :inserted_at, public?: true
update_timestamp :updated_at, public?: true
end

relationships do
belongs_to :parent, Safari.Outcrop.Outcrop, public?: true, allow_nil?: false

has_one :group, Safari.Wiki.Group,
source_attribute: :target_id,
destination_attribute: :id,
filter: expr(parent(target_type) == :group)

has_one :formation, Safari.Wiki.Formation,
source_attribute: :target_id,
destination_attribute: :id,
filter: expr(parent(target_type) == :formation)

has_one :member, Safari.Wiki.Member,
source_attribute: :target_id,
destination_attribute: :id,
filter: expr(parent(target_type) == :member)
end
And in Group I want to query all Outcrop through this table.. I thought I had done this before and I am currently stuck here (in relationships of Group):
has_many :outcrops, Outcrop do
no_attributes? true
filter expr(what_to_put_here.target_id == parent(id) and target_type == :group)
end
has_many :outcrops, Outcrop do
no_attributes? true
filter expr(what_to_put_here.target_id == parent(id) and target_type == :group)
end
Solution:
Ok for anyone else coming across this post because they want to use no_attributes? true to do some complex mapping, here is the gist of it: - You can do a has_many or has_one to any App.Domain.Resource with some prereqs: - There must be a tangible path mapped up back to what you want - In my case I had...
Jump to solution
4 Replies
Oliver
OliverOP•4mo ago
I guess I need to put in another relationship in the Group resource that points at the join table to replace the what_to_put_here This is a little bit closer, but it is also not a way to get actual Outcrop out 😄
has_many :outcrops, Outcrop do
no_attributes? true
filter expr(lithostrat_outcrop_links.target_id == parent(id) and target_type == :group)
end

has_many :lithostrat_outcrop_links, Safari.Wiki.LithostratOutcropLink,
source_attribute: :id,
destination_attribute: :target_id,
filter: expr(target_type == :group)
has_many :outcrops, Outcrop do
no_attributes? true
filter expr(lithostrat_outcrop_links.target_id == parent(id) and target_type == :group)
end

has_many :lithostrat_outcrop_links, Safari.Wiki.LithostratOutcropLink,
source_attribute: :id,
destination_attribute: :target_id,
filter: expr(target_type == :group)
the bottom one is the correct way to map up the link to the lithostrat outcrop link table at least how to utilize it as a join table to get outcrops? maybe better to set up a calc to do that? My goal here is that I want to expose group.outcrops{..} on the graphql side of things
ZachDaniel
ZachDaniel•4mo ago
You can have paths in parent expr(parent(through.thing_id) == ...) does that help?
Oliver
OliverOP•4mo ago
Does that help me select the outcrop? I will iterate a little here
Solution
Oliver
Oliver•4mo ago
Ok for anyone else coming across this post because they want to use no_attributes? true to do some complex mapping, here is the gist of it: - You can do a has_many or has_one to any App.Domain.Resource with some prereqs: - There must be a tangible path mapped up back to what you want - In my case I had - Outcrop - LithostratOutcropLink (with parent_id == outcrop, target_type == group|member|formation and target_id == the id of the group etc) - Group Solution to put on Group:
has_many :outcrops, Safari.Outcrop.Outcrop do
no_attributes? true

filter expr(
lithostrat_outcrop_links.target_id == parent(id) and
lithostrat_outcrop_links.target_type == :group
)
end
has_many :outcrops, Safari.Outcrop.Outcrop do
no_attributes? true

filter expr(
lithostrat_outcrop_links.target_id == parent(id) and
lithostrat_outcrop_links.target_type == :group
)
end
This works because outcrop has:
has_many :lithostrat_outcrop_links, LithostratOutcropLink,
public?: true,
destination_attribute: :parent_id
has_many :lithostrat_outcrop_links, LithostratOutcropLink,
public?: true,
destination_attribute: :parent_id
And that lets the filter traverse this relation and relate the ids etc with the source resource, using this middle table as an impromptu jointable.

Did you find this page helpful?