我有兩個型號 - Organization
和User
組織有許多用戶,也屬於一個所有者(老闆是User
模型太)。在父對象的多個關聯保存一個模型一次
我報名形式組織,在那裏用戶可以爲組織和name
和password
爲user
進入name
(user
是在形式上organization
嵌套對象)。成功註冊後,我需要有一個Organization
及相關的owner
(User
模型),並且此user
應屬於此組織。所以基本上,創建用戶應該是owner
,並且在註冊後應該在has_many :users
關聯列表中。
我已成功創建以用戶作爲所有者關聯的組織,但我希望用戶在創建後也可以在has_many :users
關聯中。在Rails中,我只需爲此用戶添加after_create
回調並設置organization_id
,但由於ecto沒有回調,我應該如何執行此操作?我已經閱讀了關於Ecto.Multi
,但我不確定它是否正確(對我來說看起來像是矯枉過正)並且不確定它如何用於這種情況。
爲了以防萬一,這裏是我的模型和註冊表單的代碼。
defmodule HappyClient.Organization do
use HappyClient.Web, :model
schema "organizations" do
field :name, :string
belongs_to :owner, HappyClient.User, foreign_key: :owner_id
has_many :users, HappyClient.User
timestamps()
end
def changeset(struct, params \\ %{}) do
struct
|> cast(params, [:name])
|> validate_required([:name])
end
def registration_changeset(struct, params) do
struct
|> changeset(params)
|> cast_assoc(:owner, required: true, with: &HappyClient.User.registration_changeset/2)
end
end
用戶模型
defmodule HappyClient.User do
use HappyClient.Web, :model
schema "users" do
field :email, :string
field :name, :string
field :password_hash, :string
field :is_admin, :boolean, default: false
field :is_operator, :boolean, default: false
belongs_to :organization, HappyClient.Organization
field :password, :string, virtual: true
timestamps()
end
@required_fields ~w(email name)a
@optional_fields ~w(is_admin is_operator)a
def changeset(struct, params \\ %{}) do
struct
|> cast(params, @required_fields)
|> validate_required([:email, :name])
|> validate_format(:email, ~r/@/)
|> assoc_constraint(:organization)
end
def registration_changeset(struct, params) do
struct
|> changeset(Map.merge(params, %{"is_admin" => true}))
|> cast(params, [:password], [])
|> validate_required([:password])
|> validate_length(:password, min: 6, max: 100)
|> hash_password
end
defp hash_password(changeset) do
case changeset do
%Ecto.Changeset{valid?: true,
changes: %{password: password}} ->
put_change(changeset,
:password_hash,
Comeonin.Bcrypt.hashpwsalt(password))
_ ->
changeset
end
end
end
註冊形式
<h1>Registration</h1>
<%= form_for @changeset, organization_path(@conn, :create), fn f -> %>
<%= if @changeset.action do %>
<div class="alert alert-danger">
<p>There are some errors</p>
</div>
<% end %>
<div class="form-group">
<%= text_input f, :name, placeholder: "Organization Name", class: "form-control" %>
<%= error_tag f, :name %>
</div>
<div class="form-group">
<%= inputs_for f, :owner, fn of -> %>
<%= text_input of, :name, placeholder: "Name" %>
<%= error_tag of, :name %>
<%= text_input of, :email, placeholder: "Email" %>
<%= error_tag of, :email %>
<%= password_input of, :password, placeholder: "Password" %>
<%= error_tag of, :password %>
<% end %>
</div>
<%= submit "Create Organization", class: "btn btn-primary" %>
<% end %>