Так что, если вы используете гем act-as-taggable-on и имеете следующие модели:
class User < ActiveRecord::Base
acts_as_tagger
has_many :brand_users
has_many :brands, :through => :brand_users
end
Таким образом, у вас также есть таблицы в вашей схеме:
create_table "users", :force => true do |t|
t.string "name"
end
create_table "brands", :force => true do |t|
t.string "name"
end
Тогда следующий SQL-запрос, как мы надеемся, должен делать то, что вы хотите (?):
SELECT brands.*
FROM brands
WHERE brands.id NOT IN (
SELECT brands.id
FROM brands
INNER JOIN brand_users ON brand_users.brand_id = brands.id
INNER JOIN taggings ON (taggings.tagger_id = brand_users.user_id AND taggings.tagger_type = 'User')
WHERE brand_users.user_id = 1 AND taggings.taggable_id = brand_users.brand_id
)
Чтобы перевести это в Rails ORM, я не могу приблизиться без жесткого кодирования всего суб-выбора SQLстрока, что-то вроде:
class Brand < ActiveRecord::Base
has_many :brand_users
has_many :users, :through => :brand_users
scope :has_not_been_tagged_by_user, lambda {|user| where("brands.id NOT IN (SELECT brands.id
FROM brands
INNER JOIN brand_users ON brand_users.brand_id = brands.id
INNER JOIN taggings ON (taggings.tagger_id = brand_users.user_id AND taggings.tagger_type = 'User')
WHERE brand_users.user_id = ? AND taggings.taggable_id = brand_users.brand_id)", user.id) }
end
(я знаю, что вы можете сделать это, а затем использовать ruby's .map (&: id) .join (',') , но если этоя думаю, что вы теряете много производительности, вынимая это из базы данных, конвертируя его в строку целых чисел и возвращая его обратно (насколько я понимаю).)
Затем в вашем контроллере Я думаю, что вы бы сделали что-то вроде:
@brand = current_user.brands.has_not_been_tagged_by_user(current_user)
В качестве отступления, я думаю, что на самом деле это затем выполнит SQL, как показано ниже (это правильно?):
SELECT brands.*
FROM users
INNER JOIN brand_users ON brand_users.user_id = users.id
INNER JOIN brands ON brands.id = brand_users.brand_id
WHERE brands.id NOT IN (
SELECT brands.id
FROM brands
INNER JOIN brand_users ON brand_users.brand_id = brands.id
INNER JOIN taggings ON (taggings.tagger_id = brand_users.user_id AND taggings.tagger_type = 'User')
WHERE brand_users.user_id = 1 AND taggings.taggable_id = brand_users.brand_id
) AND users.id = 1