Можно ли будет добавить дополнительные поля в ассоциацию many_to_many в ecto? - PullRequest
0 голосов
/ 24 мая 2018

Я новичок в Экто.У меня есть три таблицы, определенные в схеме Ecto, которые называются User, Role и UserRole.В UserRole мне нужно обновить дополнительное поле (например, "status" ) при связывании таблицы User и Role, которая сделает запись в таблице 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

//Ниже приведены шаги, которые я сделал

  1. Открыл iex с помощью iex -S mix
  2. Вставил запись в таблицу пользователей.

    а. userChangeset = User.changeset (% User {},% {email: "xyz@gmail.com", first_name: "xyz", last_name: "z"}) b. user1 = Repo.insert! (UserChangeset)

  3. Вставить запись в таблицу ролей.

    a. roleChangeset = Role.changeset (% Role {},% {code: "CON", описание: "Consumer"}) b. role1 = Repo.insert! (RoleChangeset)

  4. Теперь все в порядке, у меня есть запись пользователя в переменной user1 и запись роли в переменной role1 соответственно.
  5. NowМне нужно связать обе записи, чтобы вставить запись в таблице UserRole.Который будет создан автоматически при связывании записей user1 и role1
  6. Связывание записей user1 и role1 с помощью приведенной ниже команды в iex

    a. userRoleAssoc = user1 |> Repo.preload (: role) |> Ecto.Changeset.change () |> Ecto.Changeset.put_assoc (: role, [role1]) |> Repo.update!

  7. Да, он вставляет запись в UserRole, как показано ниже enter image description here

  8. Но проблема здесь в том, что мне нужно вставить статус поле для ассоциирования.Как это сделать.
  9. Я попытался обновить запись UserRole

    a. fetchUserRole = Repo.get_by (UserRole, id: 1)

    b. fetchUserRole =% {fetchUserRole |статус: «Активен»}

    c. fetchUserRole |> Ecto.Changeset.change () |> Repo.update

  10. Это дало следующий результат.В результате он был обновлен, но не отражен в моей БД.Результат остается таким же, как на изображении выше.

    {: ok,% UserRole { meta : # Ecto.Schema.Metadata <: загружен, "userroles">, компании: # Ecto.Association.NotLoaded, id: 1, is_default: false, role_id: 1, роли: # Ecto.Association.NotLoaded, статус: «Активный», user_id: 1, пользователи: # Ecto.Association.NotLoaded}}

  11. Мой вопрос здесь такой: есть ли способ вставить значение поля при ассоциировании, если это ассоциация many_to_many.Если да, значит, как это сделать.

1 Ответ

0 голосов
/ 24 мая 2018

Чтобы ответить на вопрос № 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

... потому что ваши пользователи никогда не меняют доступные роли.Просто пользовательские роли.Что позволило бы вам сделать что-то вроде ...

user = YourApp.Repo.get (YourApp.User, 1)

user
|> YourApp.User.changeset(%{user_roles: [%{role_id: 1, status: "Active"}]})
|> YourApp.Repo.update

Это возможно.Тем не менее, мне лично иногда трудно работать с cast_assoc, особенно учитывая обязательную предварительную загрузку и тонкие правила для обработки , поэтому я склонен работать непосредственно над таблицами соединений.Вот почему я упомянул в своем комментарии выше, что я запутался, почему # 9 и # 10 не работают выше.

...