2017-07-24 11 views
1

我已经成员,列表项和记忆定义为多重嵌套的变更如下:如何生成cast_assoc

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不定......

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

我发现我的方法正确加载PARAMS,但我仍然不能找到将其保存在回购(我的方式得到一个“不能将给定列表转换为字符串”)。

%{ “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 
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