Я пишу простое приложение 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 сuser_id
иorg_id
-
Контроллер со следующим действием
new
: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, class: "form-control" %> <%= text_input f, :password_confirmation, class: "form-control" %> <% end %> <%= submit "Submit", class: "btn btn-primary" %> <% end %>
Пока что так хорошо, форма хорошо выглядит.
Проблема в том, что я не совсем понимаю, каков должен быть канонический способ создания набора изменений, который я собираюсь вставить на create
, будучи в состоянии
передать его снова на представление при ошибках проверки.
Неясно, следует ли использовать один набор изменений (и как?) или явно
три набора изменений на каждый объект (User
, Org
и таблица соединений).
Как я могу проверить изменения для такой комбинированной формы, учитывая, что каждый модель/схема имеет свои собственные определенные проверки?
Параметры, которые я получаю после отправки формы, находятся в пределах %{"org" => ...}
карты, включая те, которые фактически связаны с User
. Как я должен
правильно создать форму?
Я прочитал недавно обновленный 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.
Приветствуются любые советы.