AshPhoenix.Form does not implement the Access behaviour

I'm having this problem when I try to use AshPhoenixForms. I have a liveview with this mount function:
@impl true
def mount(_conn, _session, socket) do
current_merchant = socket.assigns.current_merchant

form =
AshPhoenix.Form.for_action(current_merchant, :update_details,
as: "merchant",
api: Newco.Accounts,
actor: current_merchant
)
{:ok, assign(socket, form: form)}
end
@impl true
def mount(_conn, _session, socket) do
current_merchant = socket.assigns.current_merchant

form =
AshPhoenix.Form.for_action(current_merchant, :update_details,
as: "merchant",
api: Newco.Accounts,
actor: current_merchant
)
{:ok, assign(socket, form: form)}
end
But when I try to use in heex template the form with the following code:
<.simple_form
for={@form}
as={:merchant}
id="merchant-form"
phx-submit="save"
>
<.input field={@form[:company_name]} />
<:actions>
<.button phx-disable-with="Saving...">Save Tweet</.button>
</:actions>
</.simple_form>
</div>
<.simple_form
for={@form}
as={:merchant}
id="merchant-form"
phx-submit="save"
>
<.input field={@form[:company_name]} />
<:actions>
<.button phx-disable-with="Saving...">Save Tweet</.button>
</:actions>
</.simple_form>
</div>
I get the following in the picure attached. I can't figure out what I'm doing wrong.
No description
20 Replies
ZachDaniel
ZachDaniel3y ago
In the new phoenix versions, it is expected that you will assign the result of calling to_form/1 on the ash form We’ve updated all of the functions to be able to take a phoenix form as input
samoorai
samooraiOP3y ago
ok thanks to be clear do I only have to add this?
form =
AshPhoenix.Form.for_action(current_merchant, :update_details,
as: "merchant",
api: Newco.Accounts,
actor: current_merchant,
forms: [auto?: true]
)
|> to_form()
form =
AshPhoenix.Form.for_action(current_merchant, :update_details,
as: "merchant",
api: Newco.Accounts,
actor: current_merchant,
forms: [auto?: true]
)
|> to_form()
cause now the form works but it doesn't autopopulate the input fields
ZachDaniel
ZachDaniel3y ago
That should be it, yes. What do you mean when you say that it doesn't auto populate the input fields?
samoorai
samooraiOP3y ago
The input fields of the form should have the values of the resource in this case the merchant resource
ZachDaniel
ZachDaniel3y ago
🤔 AFAIK the to_form/1 shouldn't affect that. Are you using phoenix's builtin components? like the core_components.ex?
samoorai
samooraiOP3y ago
Yes I'm using the simple_form and the input components But the fileds are blank Although current_merchant has values
ZachDaniel
ZachDaniel3y ago
but not when you do to_form/1?
samoorai
samooraiOP3y ago
Yes even when I use that
ZachDaniel
ZachDaniel3y ago
So after making the form, try doing AshPhoenix.Form.value(form, :company_name) and see what it says
samoorai
samooraiOP3y ago
Ok it returns nil strange tried with some other values and the result is the same maybe I did something wrong it's not the forms fault because current_merchant has nil values I checked now
ZachDaniel
ZachDaniel3y ago
strange, but yeah in that case likely something in the way current_merchant is set
samoorai
samooraiOP3y ago
It's set by ash auth beacuse merchant is a user What I could do is query the database for the merchant but seems a waste Maybe there is a better way But right now I can't think of anything
ZachDaniel
ZachDaniel3y ago
🤔 Ash auth should select everything by default
samoorai
samooraiOP3y ago
now I'm at the point where current_merchant has the values but doing AshPhoenix.Form.value returns nil
IO.inspect(current_merchant)
...
#Newco.Accounts.Merchant<
__meta__: #Ecto.Schema.Metadata<:loaded, "merchants">,
id: "1b450443-ed8c-4b1e-ad23-8a9a70d9983c",
email: #Ash.CiString<"[email protected]">,
company_name: nil,
first_name: "Porco dio",
last_name: "sdf",
address: nil,
...
IO.inspect(current_merchant)
...
#Newco.Accounts.Merchant<
__meta__: #Ecto.Schema.Metadata<:loaded, "merchants">,
id: "1b450443-ed8c-4b1e-ad23-8a9a70d9983c",
email: #Ash.CiString<"[email protected]">,
company_name: nil,
first_name: "Porco dio",
last_name: "sdf",
address: nil,
...
IO.inspect(AshPhoenix.Form.value(form, :first_name))
IO.inspect(AshPhoenix.Form.value(form, :first_name))
nil
nil
should return Porco dio the complete mount code is:
@impl true
def mount(_conn, _session, socket) do
current_merchant = socket.assigns.current_merchant
IO.inspect(current_merchant)

form =
AshPhoenix.Form.for_action(current_merchant, :update_details,
as: "merchant",
api: Newco.Accounts,
actor: current_merchant,
forms: [auto?: true]
)
|> to_form()

IO.inspect(AshPhoenix.Form.value(form, :first_name))


{:ok, assign(socket, form: form)}
end
@impl true
def mount(_conn, _session, socket) do
current_merchant = socket.assigns.current_merchant
IO.inspect(current_merchant)

form =
AshPhoenix.Form.for_action(current_merchant, :update_details,
as: "merchant",
api: Newco.Accounts,
actor: current_merchant,
forms: [auto?: true]
)
|> to_form()

IO.inspect(AshPhoenix.Form.value(form, :first_name))


{:ok, assign(socket, form: form)}
end
very strange It's driving me insane I tried with other fields and with another merchant but the result is the same nil
ZachDaniel
ZachDaniel3y ago
Is :update_details an update action in the resource? What does form.source.type say
samoorai
samooraiOP3y ago
yes it is defined like so:
update :update_details do
accept [
:company_name,
:address,
:first_name,
:last_name,
:zip_code,
:city,
:fiscal_code,
:vat,
:phone,
:sdi,
:pec
]

change set_new_attribute(:company_name, arg(:company_name))
change set_new_attribute(:address, arg(:address))
change set_new_attribute(:first_name, arg(:first_name))
change set_new_attribute(:last_name, arg(:last_name))
change set_new_attribute(:zip_code, arg(:zip_code))
change set_new_attribute(:city, arg(:city))
change set_new_attribute(:fiscal_code, arg(:fiscal_code))
change set_new_attribute(:vat, arg(:vat))
change set_new_attribute(:phone, arg(:phone))
change set_new_attribute(:sdi, arg(:sdi))
change set_new_attribute(:pec, arg(:pec))
end
update :update_details do
accept [
:company_name,
:address,
:first_name,
:last_name,
:zip_code,
:city,
:fiscal_code,
:vat,
:phone,
:sdi,
:pec
]

change set_new_attribute(:company_name, arg(:company_name))
change set_new_attribute(:address, arg(:address))
change set_new_attribute(:first_name, arg(:first_name))
change set_new_attribute(:last_name, arg(:last_name))
change set_new_attribute(:zip_code, arg(:zip_code))
change set_new_attribute(:city, arg(:city))
change set_new_attribute(:fiscal_code, arg(:fiscal_code))
change set_new_attribute(:vat, arg(:vat))
change set_new_attribute(:phone, arg(:phone))
change set_new_attribute(:sdi, arg(:sdi))
change set_new_attribute(:pec, arg(:pec))
end
it says :update
ZachDaniel
ZachDaniel3y ago
Hmm…what happens if you take this set_new_attribute calls out?
samoorai
samooraiOP3y ago
okay that was the problem now works I think I didn't understand change corretly in this case it is not needed to explicitly set change (?)
ZachDaniel
ZachDaniel3y ago
Yeah, so all public attributes are accepted by defaults You don’t need to ferry them through with arguments accept [:foo, :bar, :baz] let’s you control which attributes are accepted
samoorai
samooraiOP3y ago
oh I see understood thanks a lot

Did you find this page helpful?