Мне кажется, что вы пытаетесь получить две вещи в этом запросе: 1) все сообщения, не связанные с пользователем с ограниченным = ложным, и 2) все сообщения, связанные с текущим пользователем с ограниченным = истинным.
Если я правильно понимаю, я не вижу лучшего способа сделать это, если вы хотите, чтобы это было одним запросом. Однако, если вы открыты к идее сделать два запроса, вы можете немного очистить его в коде (возможно, замедляя выполнение). Вот альтернативная установка:
class Message < ActiveRecord:Base
has_and_belongs_to_many :users
named_scope :restricted, :conditions => {:restricted => true}
named_scope :unrestricted, :conditions => {:restricted => false}
named_scope :public, :conditions => "id NOT IN (SELECT DISTINCT message_id FROM messages_users)"
end
class User < ActiveRecord:Base
has_and_belongs_to_many :messages
end
Чтобы получить список с меньшим количеством кода, но для этого нужно выполнить два обращения к базе данных:
@current_user.messages.restricted + Message.unrestricted.public
В любом случае, если в этих таблицах содержится значительный объем данных, вам необходимо убедиться, что они правильно проиндексированы, иначе это замедлится при любой нагрузке. Если это приложение с большим количеством отправляемых сообщений, вам, вероятно, будет лучше с одним запросом. Если это просто побочная функция, которая не будет использоваться очень часто, я бы, вероятно, выбрал более чистую версию.
Что, вероятно, сработало бы лучше с точки зрения модели, это избавиться от отношения HABTM и явно смоделировать отношение. Кроме того, у вас есть удобное место для отслеживания других данных о процессе отправки / доставки / получения сообщений (таких как отслеживание отправленного времени, считывание времени и т. Д.). Это не меняет ни одно из обсуждений выше, я просто предпочитаю, чтобы многие из них прошли через HABTM.
class Message < ActiveRecord:Base
has_many :subscriptions
has_many :users, :through => :subscriptions
named_scope :restricted, :conditions => {:restricted => true}
named_scope :unrestricted, :conditions => {:restricted => false}
named_scope :public, :conditions => "id NOT IN (SELECT DISTINCT message_id FROM subscriptions)"
end
class User < ActiveRecord:Base
has_many :subscriptions
has_many :messages, :through => :subscriptions
end
class Subscription < ActiveRecord:Base
belongs_to :message
belongs_to :user
end