ecto:如何访问预加载的关联的字段 [英] Ecto: How to access field of a preloaded association
问题描述
我正试图让与 friend_referral_code 没有关联的用户,或者他们的代码状态为假,并且他们也没有使用任何代码.但是我无法访问预加载的关联 friend_referral_code 的字段状态.这是我的操作方式:
I am trying to get users who have no association with friend_referral_code or their code's status is false and they haven't used any code too. But I am unable to access the field status of the preloaded association friend_referral_code. Here is how I have done this:
def get_first_free_invite_users() do
users =
list_users()
|> Repo.preload([:friend_referral_code])
|> Enum.filter(
fn u ->
u.friend_referral_code == [] or u.friend_referral_code["status"] == false and
Repo.all(from ref in FriendReferralCode,
where: ref.receiver_id == ^u.id and ref.status == true) == []
end)
users
end
它在 u.friend_referral_code.status == false
上引发错误.我无法加入的原因是FriendReferralCode中可能没有特定用户的记录,因此我想捕获这些用户.关联的加载方式如下:
It throws error on u.friend_referral_code.status == false
. The reason I cannot go for join is that there might be no record of a particular user in FriendReferralCode and I want to capture those users. This is how the association is loaded:
friend_referral_code: [
%MyApp.Accounts.FriendReferralCode{
__meta__: #Ecto.Schema.Metadata<:loaded, "friend_referral_code">,
challenge: #Ecto.Association.NotLoaded<association :challenge is not loaded>,
challenge_id: nil,
code: "RFQTS",
expiry: 1,
id: 16021,
inserted_at: ~N[2021-02-01 11:55:00],
order: 1,
prize: #Decimal<3>,
receiver: #Ecto.Association.NotLoaded<association :receiver is not loaded>,
receiver_id: 15002,
state: "create_competition",
status: false,
updated_at: ~N[2021-02-01 11:57:20],
user: #Ecto.Association.NotLoaded<association :user is not loaded>,
user_id: 15001
}
],
推荐答案
它在u.friend_referral_code.status == false上引发错误.
It throws error on u.friend_referral_code.status == false.
那是因为 u.friend_referral_code
是您的示例中的列表.您需要枚举 u.friend_referral_code
并检查每个状态.
That's because u.friend_referral_code
is a list in your example. You need to enumerate over u.friend_referral_code
and check the status on each one.
尝试这样的事情.
def get_ref_codes_by_user(id) do
Repo.all(from ref in FriendReferralCode,
where: ref.receiver_id == ^u.id and ref.status == true)
end
def filter_referrals([], user_id, acc), do: acc
def filter_referrals([ref, rest], user_id, acc) do
is_used =
ref == [] || ref.status == false && get_ref_codes_by_user(id) == []
new_acc =
case is_used do
true -> acc
false -> [ref | acc]
end
filter_referrals(rest, user_id, new_acc)
end
def get_first_free_invite_users() do
list_users()
|> Repo.preload([:friend_referral_code])
|> Enum.map(
fn u ->
filter_referrals(u.friend_referral_code, u.id, [])
end)
end
这将使您更加接近,并为您提供 FriendReferralCode
的列表列表.仔细检查逻辑是否就是您想要的.综上所述,您应该可以通过联接来做到这一点.在此处和其他
This will get you a lot closer and give you a list of list of FriendReferralCode
s. Double check that the logic is what you want here. All that said, you should be able to do this with a join. Check the docs here and this other SO answer about join types.
尝试
Repo.all(from ref in FriendReferralCode,
right_join users u on ref.user_id = u.id
where: ref.status == true)
这篇关于ecto:如何访问预加载的关联的字段的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!