Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In Rails, Using Mongoid, How do I find all Models with a valid (not nil) has_one reference?

So I have a two models like this

class ModelParent
  include Mongoid::Document
  field :name, :type => String
  has_one :model_child
end

class ModelChild
  include Mongoid::Document
  field :name, :type => String
  belongs_to :model_parent
end

Assuming I have an persisted instance of ModelParent called mp in the rails console

mc = mp.create_model_child(:name=>"child")

and then do

mp.model_child

it returns a valid object

however if I search for it like this:

ModelParent.where(:model_child.ne => nil).length

it returns 0

I've tried creating model_child and then assigning it, also using build_model_child(), and each method shows model_child is clearly in the parent, however the query for not nil (.ne) fails to find all ModelParents with children.

What am I doing wrong?

Update:

Answering my own question. I'm still unsure why the :model_child.ne => nil is not working, however...

I solved the problem by coding something like this:

  def self.with_child
    user_ids = ModelChild.all.only(:model_parent_id).map(&:model_parent_id)
    return ModelParent.where(:_id.in => user_ids).all
  end
like image 661
KDKotU Avatar asked Apr 08 '12 22:04

KDKotU


2 Answers

It is not working as foreign key is stored on belongs to side of the relationship. So, in your case ModelChild collection will have a field model_parent_id and not the other way around. I guess you had already figured that out, but instead of solving it the way you did, I would suggest you switch around the has_one and belongs_to associations and then use:

 ModelParent.where(:model_child_id.ne => nil)
like image 85
rubish Avatar answered Oct 27 '22 06:10

rubish


I found another way, but I don't know if is more efficient or less: you can use the reject method. For example:

ModelParent.all.reject{ |r| r.model_child.nil?}
like image 44
Alberto Zuin Avatar answered Oct 27 '22 07:10

Alberto Zuin