在嵌套表单上呈现变更集错误时存在一些问题。
表单呈现:
def new(conn, _) do
changeset = Organizations.Organization.create_organization_changeset(%Organization{workspace: %Workspace{}})
render(conn, "new.html", changeset: changeset)
end
表单最初呈现良好:
<%= form_for @changeset, signup_path(@conn, :create), fn f -> %>
<%= text_input f, :name, class: "form-control", required: true, autofocus: true %>
<%= label f, :organization_name %>
<%= error_tag f, :name %>
<%= inputs_for f, :workspace, fn w -> %>
<%= text_input w, :subdomain, required: true %>
<%= error_tag w, :subdomain %>
<% end %>
<% end %>
提交此表单将调用create_organization/1
:
def create_organization(attrs) do
Ecto.Multi.new()
|> Ecto.Multi.run(:organization, fn(_repo, _result) ->
changeset = Organization.create_organization_changeset(%Organization{}, attrs)
tenant = Ecto.Changeset.get_field(changeset, :slug)
Repo.insert(changeset, prefix: TenantActions.build_prefix(tenant))
end)
|> Ecto.Multi.run(:workspace, fn(_repo, %{organization: organization}) ->
attrs = %{subdomain: attrs["workspace"]["subdomain"}, organization_id: organization.id}
%Workspace{}
|> Workspace.changeset(attrs)
|> put_assoc(:organization, organization)
|> Repo.insert()
end)
|> Repo.transaction()
end
“幸福的道路”行之有效。但是,如果workspace
发生变更集错误,例如:
#Ecto.Changeset<
action: :insert,
changes: %{
name: "test",
organization: #Ecto.Changeset<action: :update, changes: %{}, errors: [],
data: #Organizations.Organization<>, valid?: true>,
organization_id: 1,
subdomain: "democompany",
tenant: "test"
},
errors: [
unique_subdomains: {"That workspace URL is not available.",
[constraint: :unique, constraint_name: "unique_subdomains"]}
],
data: #Workspaces.Workspace<>,
valid?: false
>
结果是:
(ArgumentError) could not generate inputs for :workspace from Workspaces.Workspace. Check the field exists and it is one of embeds_one, embeds_many, has_one, has_many, belongs_to or many_to_many
工作区架构:
schema "workspaces" do
field :subdomain, :string
belongs_to :organization, Pricetable.Organizations.Organization
timestamps(type: :utc_datetime_usec)
end
组织架构:
schema "organizations" do
...
field :workspace_id, :integer
has_one :workspace, Workspaces.Workspace
end
答案 0 :(得分:0)
错误消息显示:
** (ArgumentError) could not generate inputs for :workspace from Workspaces.Workspace
因此,我假设您正在传递@changeset
中的工作区,而不是组织。然后inputs_for
尝试从工作空间获取工作空间。因此,我将确保@changeset
实际上是一个组织。
此外,对于multi和inputs_for
来说使用起来都有些尴尬。 inputs_for
通常与cast_assoc/cast_embed
一起使用,后者会在内部为您设置多重播放,因此您无需手动进行操作。此处更多信息:http://blog.plataformatec.com.br/2015/08/working-with-ecto-associations-and-embeds/
或者,您放下inputs_for
并分别使用两个变更集。