凤凰号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)?在连贯性上?
对于某些特定的结构,是否没有方法可以覆盖结构相等性?
答案 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
。传递给此函数的所有其他信息都将为假。