我的会员资格,名单,项目和记忆定义如下:
schema "lists" do
has_many :itemlists, Learnit.Itemlist, on_delete: :delete_all
many_to_many :items, Learnit.Item, join_through: Learnit.Itemlist
has_many :memberships, Learnit.Membership, on_delete: :delete_all
end
schema "memberships" do
belongs_to :list, Learnit.List
has_many :memorys, Learnit.Memory, on_delete: :delete_all
end
schema "itemlists" do
belongs_to :item, Learnit.Item
belongs_to :list, Learnit.List
end
schema "items" do
has_many :itemlists, Learnit.Itemlist
many_to_many :lists, Learnit.List, join_through: Learnit.Itemlist
has_many :memorys, Learnit.Memory
end
schema "memorys" do
belongs_to :membership, Learnit.Membership
belongs_to :item, Learnit.Item
end
我的会员资格模型
def changeset(struct, params \\ %{}) do
struct
|> cast(params, [:user_id, :list_id])
|> validate_required([:user_id, :list_id])
|> cast_assoc(:memorys)
end
我的记忆模型
def changeset(struct, params \\ %{}) do
struct
|> cast(params, [:status, :membership_id, :item_id])
|> foreign_key_constraint([:membership_id, :item_id])
|> unique_constraint(:membership_id_item_id)
|> validate_required([:membership_id, :item_id])
end
我尝试创建新的成员资格并生成与一个查询相关的记忆。我需要通过其列表获得与成员资格相关联的第一个项目。然后我的计划是使用Membership的cast_assoc属性将整个保存在Repo中。
如何在会员资格的变更集中加载这些项目? 项目已经正确加载,我得到一个Map.put / 4 Undefined ...
def create(conn, %{"membership" => membership_params}) do
memories = %{}
list =
List
|> Repo.get!(membership_params["list_id"])
|> Repo.preload(:items)
|> Map.get(:items) # Get the list of items
|> Enum.map(&load_items(&1, memories)) # Loop through the list to get each item
IO.inspect(memories)
Map.put(membership_params, :memorys, memories)
membership_with_memories = Membership.changeset(%Membership{}, membership_params)
case Repo.insert(membership_with_memories) do
{:ok, _} ->
conn
|> put_flash(:info, "Membership created successfully.")
|> redirect(to: list_path(conn, :index))
{:error, membership_with_memories} ->
Logger.debug("Membership : failed to save membership")
conn
|> put_flash(:alert, "Membership was not created.")
|> redirect(to: topic_path(conn, :index))
end
end
defp load_items(item, memories) do
item
|> Map.put(memories, :item, item) # Add item to the hash
end
答案 0 :(得分:0)
我找到了正确加载params的方法,但我仍然无法找到将其保存在repo中的方法(我得到一个“无法将给定列表转换为字符串”)。
%{“list_id”=> “1”, “memorys”=> [%{“item_id”=> “1”},%{“item_id”=> “2”},%{“item_id”=> “3”}], “user_id”=> “1”}
def create(conn, %{"membership" => params}) do
memories = []
params =
List
|> Repo.get!(params["list_id"])
|> Repo.preload(:items)
|> Map.get(:items) # Get the list of items
|> Enum.map(&add_items(&1, memories)) # Loop through the list to get list of item ids
|> (&Map.put(params, "memorys", &1)).() # Add the list to membership params
|> IO.inspect()
membership_with_memories = Membership.changeset(%Membership{}, params)
case Repo.insert(membership_with_memories) do
{:ok, _} ->
conn
|> put_flash(:info, "Membership created successfully.")
|> redirect(to: list_path(conn, :index))
{:error, membership_with_memories} ->
Logger.debug("Membership : failed to save membership")
conn
|> put_flash(:error, "Membership was not created.")
|> redirect(to: list_path(conn, :index))
end
end
defp add_items(item, memories) do
memories ++ %{"item_id" => Kernel.inspect(item.id)} # Make sure id is a string
end
答案 1 :(得分:0)
刚刚在我的记忆模型中发现了问题。我真的不明白为什么validate_required会阻止cast_assoc,但对我来说这很好......
def changeset(struct, params \\ %{}) do
struct
|> cast(params, [:status, :membership_id, :item_id])
#|> foreign_key_constraint([:membership_id, :item_id]) # Dont use that !
|> unique_constraint(:membership_id_item_id) # Dont forget to put constraint on table too
|> validate_required([:item_id]) # Cannot use :membership_id with cast_assoc
end