Rails – has_one关系:关联和非关联对象的范围

我有这种关系:用户可以拥有零只或一只狗,但是狗必须属于某人。

# dog.rb class Dog < ActiveRecord::Base belongs_to :user end # user.rb class User < ActiveRecord::Base has_one :dog end 

我想定义以下范围:

 User.with_a_dog User.without_a_dog 

我可以为第一种情况执行此操作,因为默认情况下rails中的连接是INNER JOIN:

 scope :with_a_dog, :joins(:dog) 

1 /第一个范围的解决方案是否足够好?

2 /你会为第二个做什么?

3 /(有些相关)有更好的方法吗? :

 # user.rb def has_a_dog? !self.dog.nil? end 

谢谢你的帮助!

对于问题2,我认为以下内容应该有效:

 scope :without_a_dog include(:dog), where('dogs.id is null') 

其中include应该执行左连接意味着在没有狗关系的情况下连接到用户dogs.id列应该为null。

只是想添加这个以防有人发现它有用:

user.rb

 class User < ActiveRecord::Base has_one :dog # To get records with a dog we just need to do a join. # AR will do an inner join, so only return records with dogs scope :with_a_dog, -> { joins(:dog) } # To get records without a dog, we can do a left outer join, and then only # select records without a dog (the dog id will be blank). # The merge with the Dog query ensures that the id column is correctly # scoped to the dogs table scope :without_a_dog, -> { includes(:dog).merge( Dog.where(:id => nil) ) } end 

dog.rb

 class Dog < ActiveRecord::Base belongs_to :user end 

user.rb

 scope :without_a_dog, -> { includes(:dog).select { |user| user.dog.nil? } }