Mr.D
Mr.D

Reputation: 7873

Get models that do not contain another

I have two models A and B that have has_and_belongs_to_many association between them. I want to get all instances of A that are not associated by current B:

class A < ActiveRecord::Base
  def find_that_does_not_have(model_b)
    ...
  end
end

I think I have to use somethig like this:

find(:all, :conditions => [])

Is it possible?

Upvotes: 1

Views: 88

Answers (2)

W4rQCC1yGh
W4rQCC1yGh

Reputation: 2219

If I understand you correctly then one solution would be to make a corresponding class-method:

class A < ActiveRecord::Base
    def self.find_that_does_not_have(model_b)
        (A.all.map {|a| a unless a.bs.include?(model_b)}).compact
    end
end

So you can ask like this:

model_b = B.find(your_id)
A.find_that_does_not_have(model_b)

It smells like a job for a scope, but I guess I'm too noob to represent it like this at the moment :)

EDIT: With the help of user @0v3rc10ck3d I came up with a scope like this:

scope :find_that_does_not_have_b, lambda {|model_b| joins(:bs).where("b_id != #{model_b.id}")}

but it returns all model A objects regarding to relations so repetitions exist. Therefore you should add uniq while requesting:

A.find_that_does_not_have_b(model_b).uniq 

Upvotes: 1

AshwinKumarS
AshwinKumarS

Reputation: 1313

scope : find_that_does_not_have_b, lambda {|b_id| joins(:association_table).where('association_table.b_id != b_id')}

Might do the job. Couldn't test it. Call it like :

A.find_that_does_not_have_b(b_id)

Just clarifying something here. So you want a list of all A objects which is not associated to a given B object. right ?

Upvotes: 0

Related Questions