It’s not actually clear what you’re trying to accomplish here. At a glance, I can see that there are parameters for the Cart’s User, the Cart’s Product, and the paid status of the Cart.
I’m going to make an assumption here that you’re looking to see if there are any Carts for a given User that either contain a particular Product or have been paid. (This seems of dubious value, but we can extrapolate from there.)
# We’ll give names to the subsets of Carts we care about
user_owned_carts = Cart.where(user_id: current_user.id)
carts_with_product = Cart.where(product_id: params[:id])
paid_carts = Cart.where(paid: true)
# We can get all records in either set (i.e. set union) by using `or`
paid_or_containing_product = paid_carts.or(carts_with_product)
# We can get all records in both sets (i.e. set intersection) by using `where`
user_owned_carts_paid_or_containing_product = user_owned_carts.where(paid_or_containing_product)
# Now we have the set of all records that have the given user_id, and are either paid: true OR product_id: params[:id].
# To determine whether there are any matching records (with minimal DB interactions) we can use `blank?` (true if no records match) or `present?` (true if one or more records match).
# The method `count` can also be used to retrieve the exact number of matches without creating AR objects.
where returns an Active Record Relation, which represents a group of records and the set of criteria that would return those records. No query is actually run until you try to iterate over the results, which allows Active Record to compose relations together. Multiple calls to where act like a logical AND. or similarly returns a Relation, but can only be called after one or more where calls — its arguments become the right side of an (X...) OR (Y...) clause in the resulting query.
In order to change this query (for example: to test for paid carts belonging to either the current user or the identified product), we can move the various conditions around:
# WHERE paid AND (user_id OR product_id)