微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

酏剂 – 在凤凰城处理嵌套表单/ ecto变更集的正确方法是什么?

我在凤凰城写了一个简单的CRUD应用程序,管理员在创建一个新的组织时可以使用一个初始的员工帐户.

有效地组织与用户间的关系是多对多的.

我想出了以下几点:

>用户架构

defmodule MyApp.User do
use MyApp.Web,:model

schema "users" do
  field :name,:string
  field :email,:string
  field :password,:string,virtual: true
  field :password_hash,:string
end

def changeset(...) # validate email,password confirmation etc.

>组织架构

defmodule MyApp.Org do
  use MyApp.Web,:model

  schema "orgs" do
    field :official_name,:string
    field :common_name,:string

    has_many :org_staff_users,MyApp.OrgStaffUser
    has_many :users,through: [:org_staff_users,:user]
 end

 def changeset(model,params \\ :empty) do
  model
  |> cast(params,~w(official_name common_name),[])
 end

 def provisioning_changeset(model,params \\ :empty) do
   model
   |> changeset(params)
   |> cast_assoc(:org_staff_users,required: true)
 end

>结点表org_staff_users和相应的Ecto Schema
user_id和org_id
>控制器具有以下新动作:

def new(conn,_params) do
   data = %Org{org_staff_users: [%User{}]}
   changeset = Org.provisioning_changeset(data)
   render(conn,"new.html",changeset: changeset)
 end

>具有以下摘录的模板:

<%= form_for @changeset,@action,fn f -> %>
      <%= if @changeset.action do %>
        <div class="alert alert-danger">
          <p>Oops,something went wrong! Please check the errors below:</p>
          <ul>
            <%= for {attr,message} <- f.errors do %>
              <li><%= humanize(attr) %> <%= message %></li>
            <% end %>
          </ul>
        </div>
      <% end %>

    <%= text_input f,:official_name,class: "form-control" %>
    <%= text_input f,:common_name,class: "form-control" %>

    <%= inputs_for f,:org_staff_users,fn i -> %>
        <%= text_input f,:email,class: "form-control" %>
        <%= text_input f,:password,:password_confirmation,class: "form-control" %>
    <% end %>

    <%= submit "Submit",class: "btn btn-primary" %>
<% end %>

到目前为止这么好,表单很好看.

问题是,我真的不明白什么是规范的方式来构建我将要插入到创建的变更集,同时能够
将验证错误再次传递给视图.

是否应该使用一个变更集(和如何?)或明确地不清楚?
每个实体(用户,组织和联结表)有三个变化.

如何验证这种组合表单的更改,给定每个更改
模型/模式有自己的具体验证定义?

我在提交表单时收到的参数都在%{“org”=> …}
地图,包括实际上与用户有关的地图.我该怎么办
正确创建表单?

我已经阅读了最近更新的http://blog.plataformatec.com.br/2015/08/working-with-ecto-associations-and-embeds/
但我仍然困惑不解.

FWIW,我在Phoenix 1.0.4,Phoenix Ecto 2.0和Phoenix HTML 2.3.0.

任何提示将不胜感激.

解决方法

现在除了交易中的所有事情之外,您还没有任何其他选择.您将在交易中创建一个组织,该组织是自己的变更集,如果可以创建每个员工.这样的事情
if organization_changeset.valid? and Enum.all?(staff_changesets,& &1.valid?) do
  Repo.transaction fn ->
    Repo.insert!(organization_changeset)
    Enum.each staff_changesets,&Repo.insert!/1)
  end
end

注意我有效吗?检查非理想的变化集,因为它不考虑约束.如果在变更集中存在约束,则需要使用Repo.insert(不用bang!).

请记住,Ecto 2.0将会更容易.在Ecto master上,我们已经通过变更集支持belongs_to,这意味着你可以通过生成中间和结束关联来明确地做到这一点:

<%= inputs_for f,fn org_staff -> %>
  <%= inputs_for org_staff,:user,fn user -> %>
    # Your user form here
  <% end %>    
<% end %>

但是,我们也将支持多个,这将使它完全直截了当.

原文地址:https://www.jb51.cc/html/230632.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐