Rails - check if record exists in has_many association
Solution 1
Try:
current_user.items.exists?(params[:id])
Or
current_user.items.exists?(@item.id)
Solution 2
Extending @lei-liu's answer here. One can find if the record exists among the many or not, through: current_user.items.exists?(params[:id])
At the same time, exists?
allows one to filter through the columns besides id
, and also allows for more complicated conditions, like the following:
current_user.items.exists?('id > 3')
current_user.items.exists?(name: 'some_name')
Related videos on Youtube
user4584963
Updated on July 15, 2022Comments
-
user4584963 almost 2 years
I'm not sure if my question is worded correctly.
I have three models:
User
,Item
, andUserItem
.user has_many :user_items user has_many :items, through :user_items item has_many :user_items item has_many :users -> {uniq}, through :user_items item belongs_to :user user_item belongs_to :user user_item belongs_to :item
I need a way to see if a user has an item to make
if
statements in my item views But here's the catch, user_items haveenum status: [ :pending, approved]
. So I need to see if acurrent_user
has a certain:pending
item.For example when a user visits item1's view page I have the item_controller's show action declare
@item = Item.find_by_id(params[:id])
. But then what can I do with this@item
to see if a user has this item? -
user4584963 about 8 yearsI believe enum automatically adds scope
-
tkz79 about 8 yearsThis wasn't written to be something to copy and paste, it was written as an example to show the OP how to write and use a model method... and how to use his pending enumerator. The select call is a little wasteful given the uniq limitation, but someone else has already shown how to check if something exists. Way to hate without offering anything of value @AndreyDeineko.
-
Andrey Deineko about 8 years1) you do not need
self
. 2)select
would load the whole pending user_items collection into memory prior evaluating the block, thus, having tons records in collection it could potentially overwhelm the memory. 3) in this case you do not need toreturn
. 4) you could just leave theuser_items.pending.select {|s| s.user == user}.count > 0
since it will already return the boolean value. 5) sorry for the form of my first comment - it was the very morning - apologies -
user4584963 about 8 years@AndreyDeineko You mentioned a "conventional" way to accomplish this. What would that be?
-
Andrey Deineko about 8 years@user4584963 by the unconventional I meant the wrong use of
return
keyword here. -
tkz79 about 8 years@AndreyDeineko - 1+2 - I thought this was a good way to cut down the memory needs - we should only be fetching the user_items for that item, and only those that are pending... I did not know the self was unnecessary!! 3) the return habit comes from C when i took comp sci many years ago - before getting out of programming for over a decade. 4) Was thinking to set him up for more complicated functionality - agreed for this case! 5) All Good... Thanks for returning to clarify! Always enthusiastic to learn the better way!
-
drewish over 6 yearsi don't think you want a count query. if you're just checking for existence using
.exists?
would give you aSELECT ... LIMIT 1
which would stop once a match was found.