belongs_to does not add _id attributes do resource

The resource with attributes and relationships
attributes do
uuid_primary_key :id
create_timestamp :inserted_at
update_timestamp :updated_at
attribute :max_estadias_simultaneas, :integer do
allow_nil? false
default 1
end
attribute :valido_ate, :utc_datetime_usec
attribute :chaves, {:array, :string} do
allow_nil? false
default []
end
end

relationships do
belongs_to :plano, Garagem.Operacional.Plano
belongs_to :pessoa, Garagem.Operacional.Pessoa
end
attributes do
uuid_primary_key :id
create_timestamp :inserted_at
update_timestamp :updated_at
attribute :max_estadias_simultaneas, :integer do
allow_nil? false
default 1
end
attribute :valido_ate, :utc_datetime_usec
attribute :chaves, {:array, :string} do
allow_nil? false
default []
end
end

relationships do
belongs_to :plano, Garagem.Operacional.Plano
belongs_to :pessoa, Garagem.Operacional.Pessoa
end
does not have the attributes plano_id and pessoa_id. If I try to insert a record, the insert command does not have the foreign keys:
INSERT INTO "planos_contratos" ("chaves","id","inserted_at","max_estadias_simultaneas","updated_at","valido_ate") VALUES ($1,$2,$3,$4,$5,$6) [[], "a0424503-341b-476d-8522-926f600457c7", ~U[2023-09-26 04:33:13.460031Z], 1, ~U[2023-09-26 04:33:13.460031Z], ~U[2023-09-26 04:33:13.084948Z]]
INSERT INTO "planos_contratos" ("chaves","id","inserted_at","max_estadias_simultaneas","updated_at","valido_ate") VALUES ($1,$2,$3,$4,$5,$6) [[], "a0424503-341b-476d-8522-926f600457c7", ~U[2023-09-26 04:33:13.460031Z], 1, ~U[2023-09-26 04:33:13.460031Z], ~U[2023-09-26 04:33:13.084948Z]]
15 Replies
kernel
kernel2y ago
how are you inserting? you either need to set the foreign keys as writeable, or use manage_relationship to set them and you should make them not null if they shouldn't be null allow_nil?: false
barnabasj
barnabasj2y ago
I'm guessing you need to set this https://ash-hq.org/docs/dsl/ash-resource#relationships-belongs_to-attribute_writable- to true, otherwise it won't accept the ids.
Ash HQ
Ash.Resource
View the documentation for Ash.Resource on Ash HQ.
tellesleandro
tellesleandroOP2y ago
I don't know if I'm using it correct. I tried this:
plano_contrato =
Garagem.Operacional.PlanoContrato
|> Ash.Changeset.for_create(:create, %{plano: plano, pessoa: pessoa, max_estadias_simultaneas: 1, valido_ate: now, chaves: []})
|> Garagem.Operacional.create!()
plano_contrato =
Garagem.Operacional.PlanoContrato
|> Ash.Changeset.for_create(:create, %{plano: plano, pessoa: pessoa, max_estadias_simultaneas: 1, valido_ate: now, chaves: []})
|> Garagem.Operacional.create!()
and this
plano_contrato =
Garagem.Operacional.PlanoContrato
|> Ash.Changeset.for_create(:create, %{plano_id: plano.id, pessoa_id: pessoa.id, max_estadias_simultaneas: 1, valido_ate: now, chaves: []})
|> Garagem.Operacional.create!()
plano_contrato =
Garagem.Operacional.PlanoContrato
|> Ash.Changeset.for_create(:create, %{plano_id: plano.id, pessoa_id: pessoa.id, max_estadias_simultaneas: 1, valido_ate: now, chaves: []})
|> Garagem.Operacional.create!()
The define_attribute? is true by default, as it is explained in the docs. I thought I could use the belongs_to relation like I use it with Ecto.
barnabasj
barnabasj2y ago
Yes but attribute_writable is false by default. Meaning you would need to add it as an argument and set it yourself inside a change
tellesleandro
tellesleandroOP2y ago
How do I insert in a table and in its relation when getting information from a form?
barnabasj
barnabasj2y ago
I think you just need to add attribute_writable? true to your relationship definition Then the code you posted should work
tellesleandro
tellesleandroOP2y ago
Yes, I tried that and it works. Thanks. Is this the right thing to do to insert a resource and its relation at once?
barnabasj
barnabasj2y ago
I'm not sure what the exact reason is for this default, but I would guess it is because adding a relationship often has a special use case and this could potentially encourage creating your own action for it. But if the ids always have to be set when creating the resource I think this is fine. It always depends on what you are doing but if everything you do is just a create or update you lose a lot of context
tellesleandro
tellesleandroOP2y ago
I have some forms that collect information about one resource and its "children" (as post and comments), than I have to insert in the database the resource (post) and all its children (comments) at once (in the same db transaction). Is Ash able to do it? How?
barnabasj
barnabasj2y ago
You can use the manage_relationship change to accomplish this
tellesleandro
tellesleandroOP2y ago
Just a note: the doc (https://ash-hq.org/docs/dsl/ash-resource#relationships-belongs_to) say that belongs_to "creates a field on the resource with the corresponding name and type, unless define_attribute?: false is provided". It makes me think that, by default, belongs_to takes care of all the configuration.
Ash HQ
Ash.Resource
View the documentation for Ash.Resource on Ash HQ.
barnabasj
barnabasj2y ago
https://discord.com/channels/711271361523351632/1155459759743438899 this should give you an idea on how to do it
tellesleandro
tellesleandroOP2y ago
I'll do that. Thanks.
barnabasj
barnabasj2y ago
It does add the attribute, but it configures the attribute with attribute_writeable? false by default
tellesleandro
tellesleandroOP2y ago
Alright. Thanks.

Did you find this page helpful?