I’m trying to show only brand instances which the current user has not tagged, even if other users have tagged the same brand already. Something like:

Controller
This is my controller code and even though it should be working, it currently returns all brand instances.
@brand = current_user.brands.includes(:taggings).where( [ "taggings.id IS NULL OR taggings.tagger_id != ?", current_user.id ] ).order("RANDOM()").first
Schema (including my join model for good measure)
create_table "brand_users", :force => true do |t|
t.integer "brand_id"
t.integer "user_id"
t.datetime "created_at"
t.datetime "updated_at"
end
create_table "taggings", :force => true do |t|
t.integer "tag_id"
t.integer "taggable_id"
t.string "taggable_type"
t.integer "tagger_id"
t.string "tagger_type"
t.string "context"
t.datetime "created_at"
end
add_index "taggings", ["tag_id"], :name => "index_taggings_on_tag_id"
add_index "taggings", ["taggable_id", "taggable_type", "context"], :name => "index_taggings_on_taggable_id_and_taggable_type_and_context"
create_table "tags", :force => true do |t|
t.string "name"
end
end
So if you’re using the acts-as-taggable-on gem and have the following models:
So you also have the tables in your schema like:
Then the following SQL query should hopefully do what you want (?):
To translate this into Rails ORM, I can’t get any closer without hard coding the whole sub-select SQL string, something like:
(I know you could do this and then use ruby’s .map(&:id).join(‘,’) but if this is a large app I think you loose a lot of performance by taking this out of the database, converting it into a string of integers and feeding it back in (as I understand it).)
Then in your controller I think you’d do something like:
@brand = current_user.brands.has_not_been_tagged_by_user(current_user)As an aside, I think this would actually then execute an SQL like below (is that right?):