Продолжение выполнения следующего запроса, выполняющего исключение из таблицы соединений

У меня есть таблица users и таблица blocked_users. users содержит все мои данные аутентификации, настройки сайта и т. д., а blocked_users содержит source_id и target_id.

Я хотел бы вернуть коллекцию всех пользователей, которых пользователь не заблокировал и которые не заблокировали текущего пользователя.

Прямо сейчас у меня есть следующий код, который я выполняю, вызывая @user.available_users, но он выполняет три запроса. Есть ли способ сделать это одним запросом?

class User < Sequel::Model

  one_to_many :blocked_users,     :key=>:source_id
  one_to_many :blocked_by_users,  :key=>:target_id, :class => BlockedUser

  def block_user(id)
    BlockedUser.create({source_id:self.id, target_id:id})
  end 

  def blocked_user_ids
    self.blocked_users.map{|bu| bu[:target_id]}
  end 

  def blocked_by_user_ids
    self.blocked_by_users.map{|bu| bu[:target_id]}
  end 

  def available_users
    User.exclude(:id=>self.blocked_users.map{|bu| bu[:target_id]}).exclude(:id=>self.blocked_by_users.map{|bu| bu[:target_id]})
  end 
end

Я добавил следующий метод в свой класс User:

  def test_avail
    User.exclude(:blocked_users=>self).exclude(:blocked_by_users=>self)
  end 

1.9.3p0 :001 > User.all.first.test_avail
   INFO - (0.000732s) SELECT * FROM `users`
Sequel::Error: invalid association class User for association :blocked_users used in dataset filter for model User, expected class BlockedUser

person jdkealy    schedule 28.06.2012    source источник


Ответы (1)


Использование фильтра по поддержке ассоциаций, вероятно, проще всего:

def available_users
  User.exclude(:blocked_users=>self).exclude(:blocked_by_users=>self)
end
person Jeremy Evans    schedule 28.06.2012
comment
Эй, поэтому я добавил изменения в вопрос выше, но теперь с этим фрагментом я получаю Sequel::Error: недопустимый класс ассоциации Пользователь для ассоциации: blocked_users используется в фильтре набора данных для пользователя модели, ожидаемый класс BlockedUser - person jdkealy; 28.06.2012
comment
Виноват. Код работал бы, если бы block_users и block_by_users были самореферентными ассоциациями many_to_many. Вместо этого вы используете отдельный класс BlockedUser и ассоциации one_to_many. Я не уверен, почему вы так настроили. С вашим текущим кодом вы сможете выполнить User.exclude(:id=›self.blocked_users_dataset.select(:target_id)). - person Jeremy Evans; 29.06.2012