Hi,
First of all sorry, i don’t know how to put this scenario as title. I am working with forms contains this scenario.
- Create company with user. This one has manage_relationships which
has_many
with the:users
relationship like this:
create :create_company_with_user do
accept [:name, :registration_number]
# argument :generate_hash?, :boolean, default: false
argument :user, :map, allow_nil?: false
# change {Mgx.Company.Changes.RegistrationNumber, generate_hash?: :generate_hash?}
change manage_relationship(:user, :users, type: :create)
end
- Now for the user
primary action
is this which haspersonal_information
hashas_one
relationship with theuser
like this(From Ash authentication, I made another action)
create :register_with_password_with_personal_details do
description "Register a new user with a email and password and personal information"
primary? true
argument :email, :ci_string do
allow_nil? false
end
argument :password, :string do
description "The proposed password for the user, in plain text."
allow_nil? false
constraints min_length: 8
sensitive? true
end
argument :password_confirmation, :string do
description "The proposed password for the user (again), in plain text."
allow_nil? false
sensitive? true
end
argument :personal_information, :map do
allow_nil? false
end
validate match(:email, ~r/@/), message: "must be a valid email"
# Sets the email from the argument
change set_attribute(:email, arg(:email))
# Hashes the provided password
change AshAuthentication.Strategy.Password.HashPasswordChange
# Generates an authentication token for the user
change AshAuthentication.GenerateTokenChange
# Manage the relationship with the personal information
change manage_relationship(:personal_information, :personal_information,
type: :direct_control
)
# validates that the password matches the confirmation
validate AshAuthentication.Strategy.Password.PasswordConfirmationValidation
metadata :token, :string do
description "A JWT that can be used to authenticate the user."
allow_nil? false
end
end
So my relationships are:
- company
has_many
users - user
has_one
personal_information
I tried to mount the the form like this:
def mount(_params, _session, socket) do
form =
Mgx.Company.form_to_create_company_with_user(forms: [auto?: true])
|> AshPhoenix.Form.add_form([:user])
|> AshPhoenix.Form.add_form([:user, :personal_information])
{:ok,
assign(socket,
form: to_form(form)
)}
end
Immediately I get this warning when mounted and registration fails when submitted:
warning] Unhandled error in form submission for Mgx.Accounts.User.register_with_password_with_personal_details
This error was unhandled because Ash.Error.Framework.AssumptionFailed does not implement the `AshPhoenix.FormData.Error` protocol.
** (Ash.Error.Framework.AssumptionFailed) Assumption failed: Action does not correlate with an authentication strategy
This should not be possible, please report a detailed bug at:
https://github.com/ash-project/ash/issues/new?assignees=&labels=bug%2C+needs+review&template=bug_report.md&title=
[warning] Unhandled error in form submission for Mgx.Accounts.User.register_with_password_with_personal_details
This error was unhandled because Ash.Error.Framework.AssumptionFailed does not implement the `AshPhoenix.FormData.Error` protocol.
** (Ash.Error.Framework.AssumptionFailed) Assumption failed: Action does not correlate with an authentication strategy
This should not be possible, please report a detailed bug at:
https://github.com/ash-project/ash/issues/new?assignees=&labels=bug%2C+needs+review&template=bug_report.md&title=
This form successfully render though:
<.simple_form for={@form} phx-change="validate" phx-submit="save">
<.input field={@form[:name]} label="Company Name" />
<.input field={@form[:registration_number]} label="Company Registration Number" />
<.inputs_for :let={user} field={@form[:user]}>
<.input field={user[:email]} label="Email" type="email" />
<.inputs_for :let={personal_information} field={user[:personal_information]}>
<.input field={personal_information[:first_name]} label="First Name" />
<.input field={personal_information[:last_name]} label="Last Name" />
<.input field={personal_information[:country_code]} label="Country Code" />
<.input field={personal_information[:phone_number]} label="Phone Number" />
</.inputs_for>
</.inputs_for>
<:actions>
<.button class="w-full bg-[#262262] hover:bg-[#0C0944]">Register</.button>
</:actions>
</.simple_form>
Side Note: If I remove the manage_relationship
of personal_information
in the user, I can successfully submit the form. with company and user. while removing add_form([:user, :personal_information]
Maybe mount function I am assigning wrong? As always any help would be greatly appreciated thank you.
This is total Form I see when I submit:
[error] Registration failed: %Phoenix.HTML.Form{
source: #AshPhoenix.Form<
resource: Mgx.Company.CompanyInformation,
action: :create_company_with_user,
type: :create,
params: %{
"name" => "Hatfield and Vega Associates",
"registration_number" => "Gamble Cotton Trading",
"user" => %{
"_form_type" => "create",
"_persistent_id" => "0",
"_touched" => "_form_type,_persistent_id,_touched,_unused_email,email,personal_information",
"email" => "rocysog@mailinator.com",
"password" => "password",
"password_confirmation" => "password",
"personal_information" => %{
"_form_type" => "create",
"_persistent_id" => "0",
"_touched" => "_form_type,_persistent_id,_touched,_unused_country_code,_unused_first_name,_unused_last_name,_unused_phone_number,country_code,first_name,last_name,phone_number",
"country_code" => "Tenetur enim ipsam q",
"first_name" => "Troy",
"last_name" => "Lewis",
"phone_number" => "+1 (358) 257-3731"
}
}
},
source: #Ash.Changeset<
domain: Mgx.Company,
action_type: :create,
action: :create_company_with_user,
attributes: %{
name: "Hatfield and Vega Associates",
status: :pending,
registration_number: "Gamble Cotton Trading"
},
relationships: %{
users: [
{[
%{
"_form_type" => "create",
"_persistent_id" => "0",
"_touched" => "_form_type,_persistent_id,_touched,_unused_email,email,personal_information",
"email" => "rocysog@mailinator.com",
"password" => "password",
"password_confirmation" => "password",
"personal_information" => %{
"_form_type" => "create",
"_persistent_id" => "0",
"_touched" => "_form_type,_persistent_id,_touched,_unused_country_code,_unused_first_name,_unused_last_name,_unused_phone_number,country_code,first_name,last_name,phone_number",
"country_code" => "Tenetur enim ipsam q",
"first_name" => "Troy",
"last_name" => "Lewis",
"phone_number" => "+1 (358) 257-3731"
}
}
],
[
ignore?: false,
on_missing: :ignore,
on_match: :ignore,
on_lookup: :ignore,
on_no_match: :create,
eager_validate_with: false,
authorize?: true,
meta: [id: :user],
type: :create
]}
]
},
arguments: %{
user: %{
"_form_type" => "create",
"_persistent_id" => "0",
"_touched" => "_form_type,_persistent_id,_touched,_unused_email,email,personal_information",
"email" => "rocysog@mailinator.com",
"password" => "password",
"password_confirmation" => "password",
"personal_information" => %{
"_form_type" => "create",
"_persistent_id" => "0",
"_touched" => "_form_type,_persistent_id,_touched,_unused_country_code,_unused_first_name,_unused_last_name,_unused_phone_number,country_code,first_name,last_name,phone_number",
"country_code" => "Tenetur enim ipsam q",
"first_name" => "Troy",
"last_name" => "Lewis",
"phone_number" => "+1 (358) 257-3731"
}
}
},
errors: [],
data: #Mgx.Company.CompanyInformation<
company_documents: #Ash.NotLoaded<:relationship, field: :company_documents>,
company_tdls: #Ash.NotLoaded<:relationship, field: :company_tdls>,
company_gasx_profile: #Ash.NotLoaded<:relationship, field: :company_gasx_profile>,
company_lngx_profile: #Ash.NotLoaded<:relationship, field: :company_lngx_profile>,
billing_address: #Ash.NotLoaded<:relationship, field: :billing_address>,
business_address: #Ash.NotLoaded<:relationship, field: :business_address>,
users: #Ash.NotLoaded<:relationship, field: :users>,
__meta__: #Ecto.Schema.Metadata<:built, "company_informations">,
id: nil,
name: nil,
registration_number: nil,
website: nil,
subscription_plan: nil,
status: :pending,
last_registration_submitted_at: nil,
inserted_at: nil,
updated_at: nil,
aggregates: %{},
calculations: %{},
...
>,
valid?: true
>,
name: "form",
data: nil,
form_keys: [
user: [
create_action: :register_with_password_with_personal_details,
create_resource: Mgx.Accounts.User,
type: :single,
forms: [
personal_information: [
type: :single,
forms: [],
sparse?: false,
managed_relationship: {Mgx.Accounts.User, :personal_information,
[
on_lookup: :ignore,
on_no_match: {:create, :create},
on_match: {:update, :update},
on_missing: {:destroy, :destroy},
type: :direct_control
]},
must_load?: false,
updater: #Function<36.69732248/1 in AshPhoenix.Form.Auto.related/3>
]
],
sparse?: false,
managed_relationship: {Mgx.Company.CompanyInformation, :users,
[
on_missing: :ignore,
on_lookup: :ignore,
on_no_match: {:create, :register_with_password_with_personal_details},
on_match: :ignore,
type: :create
]},
must_load?: false
]
],
forms: %{
user: #AshPhoenix.Form<
resource: Mgx.Accounts.User,
action: :register_with_password_with_personal_details,
type: :create,
params: %{
"_form_type" => "create",
"_persistent_id" => "0",
"_touched" => "_form_type,_persistent_id,_touched,_unused_email,email,personal_information",
"email" => "rocysog@mailinator.com",
"password" => "password",
"password_confirmation" => "password",
"personal_information" => %{
"_form_type" => "create",
"_persistent_id" => "0",
"_touched" => "_form_type,_persistent_id,_touched,_unused_country_code,_unused_first_name,_unused_last_name,_unused_phone_number,country_code,first_name,last_name,phone_number",
"country_code" => "Tenetur enim ipsam q",
"first_name" => "Troy",
"last_name" => "Lewis",
"phone_number" => "+1 (358) 257-3731"
}
},
source: #Ash.Changeset<
domain: Mgx.Accounts,
action_type: :create,
action: :register_with_password_with_personal_details,
attributes: %{
role: :company_admin,
email: #Ash.CiString<"rocysog@mailinator.com">
},
relationships: %{
personal_information: [
{[
%{
"_form_type" => "create",
"_persistent_id" => "0",
"_touched" => "_form_type,_persistent_id,_touched,_unused_country_code,_unused_first_name,_unused_last_name,_unused_phone_number,country_code,first_name,last_name,phone_number",
"country_code" => "Tenetur enim ipsam q",
"first_name" => "Troy",
"last_name" => "Lewis",
"phone_number" => "+1 (358) 257-3731"
}
],
[
ignore?: false,
on_missing: :destroy,
on_match: :update,
on_lookup: :ignore,
on_no_match: :create,
eager_validate_with: false,
authorize?: true,
meta: [id: :personal_information],
type: :direct_control
]}
]
},
arguments: %{
(truncated)