Phoenix检查模型(例如用户)是否相等

时间:2019-04-09 08:24:40

标签: elixir phoenix-framework

凤凰号n00b在这里。

所以我有一个当前登录用户(使用Coherence,但我认为这对这里没有影响):

user = Coherence.current_user(conn)

我有一个与用户有关系的对象:

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

我只想检查user是否与owner相同。

  • user == owner是不正确的,因为-我猜-结构是引用,因此尽管是相同的DB对象,但两者还是会有所不同。

  • user.id == owner.id应该可以,但是由于user可以是nil,所以在这种情况下将失败,而等式仍然成立。

  • 我尝试了user[:id] == owner[:id],因为如果user为nil不会失败,但是如果它为user,则会出现User does not implement the Access behaviour错误。 :(

  • not is_nil(user) && user.id == owner.id可以但很丑陋(感谢上帝owner也是可以忍受的)

我想我这里需要一个辅助函数,但是它不是内置的吗?如果是这样,在哪里?在埃克托(Ecto)?在连贯性上?

对于某些特定的结构,是否没有方法可以覆盖结构相等性?

3 个答案:

答案 0 :(得分:1)

为什么不将条件放入查询中?

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

编辑:已更改为希望更接近发布者想要的内容

答案 1 :(得分:0)

我建议:owner = Map.get(object, :user, %{})。您现在将有2张地图进行比较。 然后,您可以使用user[:id] == owner[:id]

答案 2 :(得分:0)

正如我在评论中所说,仅比较id可能是一个坏主意,因为即使您比较不同类型的结构,它也会返回true。最好的选择是创建一个比较功能。以下内容可能会为您服务。

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

这使用模式匹配来确保两个参数都是结构,并且来自同一模块,并且它们具有相同的id。传递给此函数的所有其他信息都将为假。