How to delete objects through a named scope?

1.8k views Asked by At

There is a join table with three columns: id, product_a_id, product_b_id

class ProductConnection < ActiveRecord::Base
  belongs_to :product_a, class_name: :Product
  belongs_to :product_b, class_name: :Product    
end

I would like to filter the table by a specific product regardless in which column the product id is contained. How can I write a named scope which respects that a product can be nil? The following draft is inspired by a post by Zack Holman though it does not work:

scope :find_by_product, \
  lambda {|p| p.nil? ? { \
    where(["product_a_id = ? OR product_b_id = ?", p.id, p.id]) : {} \
  }

Then I would like to know how I can delete all products returned in the ActiveRecord::Relation?

1

There are 1 answers

5
pdobb On BEST ANSWER

It sounds like the issue is with how to make your find_by_product scope work when the passed in product is nil? I think your curly braces are a little mixed up. Either way, here's how I'd write it in case this helps:

ProductConnection

scope :for_product, ->(product) {
  if product_id = product.try(:id)
    where(arel_table[:product_a_id].eq(product_id).
            or(arel_table[:product_b_id].eq(produt_id))
  end
}

Then, once that works, you can just call destroy_all on the scope to destroy all the records.

ProductConnection.for_product(my_product).destroy_all

There is also delete_all, which you can use in the same way, if you really don't want the ActiveRecord callbacks included with destroy.