Rails - отношение has_one: области видимости для связанных и не связанных объектов - PullRequest
4 голосов
/ 20 апреля 2011

У меня есть такие отношения: у пользователя может быть ноль или одна собака, но собака должна принадлежать кому-то.

# 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

Я могу сделать это для первого случая, потому что соединения по умолчанию являются INNER JOIN в rails:

scope :with_a_dog, :joins(:dog)

1 / Достаточно ли хорошо это решение для первой области?

2 / Что бы вы сделали для второго?

3 / (в некоторой степени связано) Есть ли лучший способ сделать это? :

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

Спасибо за вашу помощь!

Ответы [ 3 ]

4 голосов
/ 23 января 2015

Просто хотел бы добавить это на тот случай, если кому-то это будет полезно:

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
1 голос
/ 24 апреля 2017

user.rb

scope :without_a_dog, -> {
    includes(:dog).select { |user| user.dog.nil? }
  }
1 голос
/ 20 апреля 2011

Для вопроса 2 я думаю, что должно работать следующее:

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

Где include должен выполнять левое соединение, что означает, что там, где нет отношения dog для соединения с пользователем, столбец dogs.id должен быть нулевым.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...