Reputation: 2415
Using Rails 5.0:
class User < ApplicationRecord
belongs_to :cart, {:optional => true}
end
class Phone < ApplicationRecord
has_many :cart_items
end
class CartItem < ApplicationRecord
belongs_to :cart, {:optional => true} #has cart_id as column
belongs_to :phone, {:optional => true} #has phone_id as column
end
class Cart < ApplicationRecord
has_one :user
has_many :cart_items
end
My app works as follows. There are users (User
), that have carts (Cart
), and in those carts have cart items (CartItem
). In each of those cart items there is information regarding the cart including what phones are purchased (Phone
).
I am currently using an .each
loop to loop through user.cart.cart_items
, if it returns a cart item has params[:phone_id]
, then it would update it and break from the loop.
user_items = @user.cart.cart_items
if user_items.any?{|x| x.phone_id == params[:phone_id].to_i}
user_items.each do |x|
if x.phone_id == params[:phone_id].to_i
x.update_attributes(:quantity_sold => params[:quantity].to_i)
break
end
end
end
Although it works, I was wondering whether there was a way to use a database query to find all associated phones associated with the user_items (@user.cart.cart_items
). Note: @user
is just the current user logged in.
I tried using @user.cart.cart_items.where(:phone_id => 1)
, and it worked, but when trying to retrieve the phone from there via the query @user.cart.cart_items.where(:phone_id => 1).phone
, it returned the error undefined method 'phone' for #<CartItem::ActiveRecord_AssociationRelation:0x007fa38a461128>
.
I checked to see whether my associations were set up correctly via (cart_item.phones
, and phone.cart_items
, and they worked fine (cart_item
= instance of CartItem
and phone
= instance of Phone
).
Is there a way I can use a database query from an association to find all user cart items (@user.cart.cart_items
) that have a phone id of x (params)? Note: I need the actual object, so I can look through fields of the phone (i.e.: @user.cart.cart_items.phone.brand_name
.)
Upvotes: 0
Views: 54
Reputation: 1403
This gives you related CartItems:
user_items_with_matching_phone = @user.cart.cart_items.where(phone_id: x)
To get the first item's phone:
user_items_with_matching_phone.first.phone
To update the first item (basically what you did in the each loop):
user_items_with_matching_phone.first.update_attributes(quantity_sold: params[:quantity].to_i)
However, you can not do user_items_with_matching_phone.phone
because user_items_with_matching_phone
is more similar to an array than a single object. You can get the length if by user_items_with_matching_phone.size
Upvotes: 2