我是Ecto的新手。我在Ecto架构中定义了三个名为User,Role和UserRole的表。在UserRole中,我需要在关联User和Role表时更新其他字段(例如“status”),这将在UserRole表中生成一个条目。
// User Schema
schema "users" do
field :first_name, :string
field :last_name, :string
field :email, :string
many_to_many :roles, Role, join_through: "userroles"
end
// Role Schema
schema "roles" do
field :code, :string
field :description, :string
many_to_many :users, User, join_through: "userroles"
end
// UserRole Schema
schema "userroles" do
field :is_default, :boolean, default: false
field :status, :string
field :user_id, :id
field :role_id, :id
belongs_to :users, User, define_field: false
belongs_to :roles, Role, define_field: false
end
//以下是我已经完成的步骤
在用户表格中插入记录。
一个。 userChangeset = User.changeset(%User {},%{email:“xyz @ gmail.com”,first_name:“xyz”,last_name:“z”}) 湾 user1 = Repo.insert!(userChangeset)
在角色表中插入记录。
一个。 roleChangeset = Role.changeset(%Role {},%{code:“CON”,description:“Consumer”}) 湾 role1 = Repo.insert!(roleChangeset)
使用iex
中的以下命令关联user1和role1记录一个。 userRoleAssoc = user1 |> Repo.preload(:roles)|> Ecto.Changeset.change()|> Ecto.Changeset.put_assoc(:roles,[role1])|> Repo.update!
我尝试更新UserRole记录
一个。 fetchUserRole = Repo.get_by(UserRole,id:1)
湾 fetchUserRole =%{fetchUserRole |状态:“有效”}
℃。 fetchUserRole |> Ecto.Changeset.change()|> Repo.update
它给出了以下结果。在结果中它得到更新但没有反映在我的数据库中。结果与上图一样。
{:确定, %UserRole的{ meta :#Ecto.Schema.Metadata<:loaded,“userroles”>, 公司:#Ecto.Association.NotLoaded, id:1, is_default:false, role_id:1, 角色:#Ecto.Association.NotLoaded, 状态:“有效”, user_id:1, 用户:#Ecto.Association.NotLoaded }}
我的问题是,是否有任何方法可以在关联时插入字段值,如果它是一个many_to_many关联。如果是,则表示如何做到。
答案 0 :(得分:1)
要真正回答#11,有一个关于您需要回答的业务逻辑的问题:
当您的用户将用户分配给某个角色时,他们是否创建新角色?或者只选择预定义的角色?
我会想象它是后者。如果是这样,我会想你可以做以下事情......
defmodule YourApp.User do
use Ecto.Schema
import Ecto.Changeset
schema "users" do
...
has_many :user_roles, YourApp.UserRole
end
def changeset(user, params) do
user
|> cast_things...
|> cast_assoc(:user_roles)
end
end
...因为您的用户永远不会更改可用的角色。只是UserRoles。哪个会让你做点像......
user = YourApp.Repo.get(YourApp.User,1)
user
|> YourApp.User.changeset(%{user_roles: [%{role_id: 1, status: "Active"}]})
|> YourApp.Repo.update
这是一种可能性。但是,我个人觉得与cast_assoc
一起工作有时难以理解,特别是考虑到the preloading required and nuanced rules to process,所以我倾向于直接处理连接表。这就是为什么我在上面的评论中提到,我很困惑为什么#9和#10不能在上面工作。