1

I have a Rails 4.2, Mongoid 4 project with these models:

class Customer #aka Company
  include Mongoid::Document

  has_many :branches
end

class Branch
  include Mongoid::Document  

  field :name, type: String, default: ""

  belongs_to :customer
end

I want to find all the Customers (aka Companies) that have a branch with name "New York". I would think that this code would work:

branches = Branch.where(name: "New York").map(&:_id)
=> [BSON::ObjectId('54f76cef6272790316390100')]
Customer.where(:branch_ids => branches).entries

However, it always returns an empty array, no matter what I try. In place of branch_ids, I've also tried branches, branch, branches_id, and others, but to no avail. I've also tried to convert the BSON::ObjectID to plain string, but that doesn't work either.

So, basically, how can I search a model based on an array of association ids? Thanks.

Ryan K
  • 3,985
  • 4
  • 39
  • 42

2 Answers2

1

If the relations are

Customer has_many :branches and

Branch belongs_to :customer,

Then branches collection will have a customer_id column and not the reverse. So you can do

cust_ids = Branch.where(name: "New York").map(&:customer_id)
Customer.find(cust_ids)

Since you need only the customer ids from the first query, it is advisable to use pluck

cust_ids = Branch.where(name: "New York").pluck(:customer_id)
Santhosh
  • 28,097
  • 9
  • 82
  • 87
  • That does work (don't know why I didn't think of it), but it seems like a workaround. I know that there isn't a column of `branch_ids`, but there is a method. I just don't know if you can search via a method. – Ryan K Mar 11 '15 at 16:43
0

You can use Symbol#elem_match like this:

Customer.where(:branches.elem_match => { name: "New York" })

And Queryable#elem_match like this:

Customer.elem_match(branches: { name: "New York" })

Both query will give return you Customers of 'New York' branches.

Sharvy Ahmed
  • 7,247
  • 1
  • 33
  • 46