Elixir Ecto:如何存储关于多对多关系的元信息

时间:2018-05-08 08:48:14

标签: elixir ecto

我们说我有模型UserOrganization以及两者之间的多对多关系。我现在想要添加关于两者之间关系的信息。例如timestampsposition。我该怎么做以及如何查询这些信息?

我认为正确的方向是使用连接架构。遵循以下Ecto文档:

defmodule UserOrganization do
  use Ecto.Schema

  @primary_key false
  schema "users_organizations" do
    field :position, :string # adding information on the position of the user within the organization
    belongs_to :user, User
    belongs_to :organization, Organization
    timestamps # Added bonus, a join schema will also allow you to set timestamps
  end

  def changeset(struct, params \\ %{}) do
    struct
    |> Ecto.Changeset.cast(params, [:user_id, :organization_id])
    |> Ecto.Changeset.validate_required([:user_id, :organization_id])
    # Maybe do some counter caching here!
  end
end

defmodule User do
  use Ecto.Schema

  schema "users" do
    many_to_many :organizations, Organization, join_through: UserOrganization
  end
end

defmodule Organization do
  use Ecto.Schema

  schema "organizations" do
    many_to_many :users, User, join_through: UserOrganization
  end
end

# Then to create the association, pass in the ID's of an existing
# User and Organization to UserOrganization.changeset
changeset = UserOrganization.changeset(%UserOrganization{}, %{user_id: id, organization_id: id})

case Repo.insert(changeset) do
  {:ok, assoc} -> # Assoc was created!
  {:error, changeset} -> # Handle the error
end

现在,如何在创建记录时设置position,如何查询timestampsposition

1 个答案:

答案 0 :(得分:1)

如果您想要检索复合模式的timestampsposition,可以在has_manyUser上添加Organization个关系,例如此

defmodule Organization do
  use Ecto.Schema

  schema "organizations" do
    many_to_many :users, User, join_through: UserOrganization
    has_many :user_organizations, UserOrganization
  end
end

然后,当您检索Repo.preloaduser_organizations的所有属性都可用时,您可以Organization UserOrganization {/ 1}}。

关于如何设置position,您只需将其添加到变更集中,并确保允许UserOrganization架构上的参数

 def changeset(struct, params \\ %{}) do
    struct
    |> Ecto.Changeset.cast(params, [:user_id, :organization_id, :position])
    |> Ecto.Changeset.validate_required([:user_id, :organization_id])
    # Maybe do some counter caching here!
  end

changeset = UserOrganization.changeset(%UserOrganization{}, %{user_id: id, organization_id: id, position: position})

它应该对你很好。