Феникс проверить модель (например, пользователь) равенство - PullRequest
1 голос
/ 09 апреля 2019

Phoenix n00b здесь.

Итак, я вошел в систему текущего пользователя (используя Coherence , но я не думаю, что это повлияет здесь):

user = Coherence.current_user(conn)

И у меня есть объект, который связан с пользователем:

object = Repo.get(Object, XX) |> Repo.preload(:user)
owner = object.user

Я просто хочу проверить, что user совпадает с owner.

  • Запись user == owner не является правильной, потому что - я полагаю - структуры являются ссылками, поэтому они будут различаться, несмотря на то, что они являются одним и тем же объектом БД.

  • Запись user.id == owner.id будет работать, нопоскольку user может быть nil, в этом случае произойдет сбой, в то время как равенство остается верным.

  • Я попытался user[:id] == owner[:id], поскольку это не дает сбоя, если userноль, но тогда, если это user, я получаю ошибку User does not implement the Access behaviour.: (

  • Письмо not is_nil(user) && user.id == owner.id работает, но уродливо (и, слава богу, owner также не скупо)

Думаю, яПонадобится ли здесь вспомогательная функция, но разве она не встроена? Если да, то где? В Ecto? В Coherence?

Нет ли способа переопределить структурное равенство для некоторых конкретных структур?

Ответы [ 3 ]

1 голос
/ 09 апреля 2019

Почему бы не указать условие в запросе?

owner = some_struct

from(
  o in Object, 
  where: o.user_id == ^owner.id and not is_nil(o.user_id), 
  preload: [:user]
) 
|> Repo.one # !only works if db returns max one row!
|> case do
  nil ->    # no matches in db
  object -> # object.user.id == object.user_id == owner.id here
end

Редактировать: изменилось на что-то более близкое к тому, что хочет плакат

0 голосов
/ 10 апреля 2019

Как я сказал в комментариях, сравнение только идентификаторов, вероятно, является плохой идеей, потому что он вернул бы true, даже если вы сравниваете различные типы структур. Лучше всего было бы создать функцию сравнения. Возможно, вам подойдет что-то вроде следующего.

def compare_structs(%mod{id: id}, %mod{id: id}), do: true
def compare_structs(_, _), do: false

При этом используется сопоставление с образцом, чтобы убедиться, что оба аргумента являются структурами, а также исходят из одного и того же модуля и имеют одинаковый id. Все остальное, переданное этой функции, будет ложным.

0 голосов
/ 09 апреля 2019

Я бы предложил: owner = Map.get(object, :user, %{}). Теперь у вас будет 2 карты для сравнения. Затем вы можете использовать user[:id] == owner[:id]

...