以下是我目前拥有的三种型号
routine.ex
defmodule DailyRoutine.Routine do
use DailyRoutine.Web, :model
schema "routines" do
field :title, :string
field :timeframe, :integer
field :content, :string
belongs_to :user, DailyRoutine.User
has_many :comments, DailyRoutine.Comment
timestamps
end
@required_fields ~w(title timeframe content)
@optional_fields ~w()
# rest of the code goes here
end
user.ex
defmodule DailyRoutine.User do
use DailyRoutine.Web, :model
schema "users" do
field :name, :string
field :username, :string
field :password, :string, virtual: true
field :password_hash, :string
has_many :routines, DailyRoutine.Routine
has_many :comments, DailyRoutine.Comment
timestamps
end
@required_fields ~w(name username)
@optional_fields ~w()
# rest of the model code goes here
end
comment.ex
defmodule DailyRoutine.Comment do
use DailyRoutine.Web, :model
schema "routines" do
field :content, :string
belongs_to :user, DailyRoutine.User
belongs_to :routine, DailyRoutine.Routine
timestamps
end
@required_fields ~w(user_id routine_id content)
@optional_fields ~w()
#rest of the code goes here
end
现在问题是我无法在控制器中找到一种方法来执行多个build_assoc
并将它们链接在一起以构建适当的变更集。
这是我的控制器:
comment_controller.ex
defmodule DailyRoutine.CommentController do
use DailyRoutine.Web, :controller
alias DailyRoutine.Comment
def create(conn, %{"routine_id" => routine_id, "comment" => comment_params}, user) do
routine = Repo.get!(DailyRoutine.Routine, routine_id) |> Repo.preload(:user)
changeset =
user
|> build_assoc(:comments)
|> Repo.preload(:routine)
|> Comment.changeset(comment_params)
|> Ecto.Changeset.put_assoc(:routine, routine)
case Repo.insert(changeset) do
{:ok, comment} ->
conn
|> put_flash(:info, "Your comment was successfully posted!")
|> redirect(to: routine_path(conn, :show, routine_id))
{:error, changeset} ->
redirect(conn, to: routine_path(conn, :show, routine_id))
end
end
def action(conn, _) do
apply(__MODULE__, action_name(conn), [conn, conn.params, conn.assigns.current_user])
end
end
到目前为止我所做的并不起作用,我尝试了多种方法,包括使用特定关系id
等手动构建结构。
非常感谢!
答案 0 :(得分:3)
I would simply put the ids in manually in the struct and pass that to Comment.changeset/2
for this instead of trying to use build_assoc
since you already have routine
and its user
loaded:
changeset =
%Comment{user_id: user.id, routine_id: routine_id}
|> Comment.changeset(comment_params)
case Repo.insert(changeset) do
...
end
Since you have routine_id
and user_id
in the @required_fields
, you can also put these ids in the params you pass to Comment.changeset/2
:
comment_params =
comment_params
|> Map.put("user_id", user.id)
|> Map.put("routine_id", routine_id)
changeset = Comment.changeset(%Comment{}, comment_params)