0

У меня есть модель Node, которая имеет виртуальный атрибут user_tags.Как мне выполнять запросы по виртуальным атрибутам?

Это то, что он выглядит на консоли:

[42] pry(main)> n = Node.first 
    Node Load (0.5ms) SELECT "nodes".* FROM "nodes" ORDER BY "nodes"."id" ASC LIMIT 1 
=> #<Node id: 6, name: "10PP Form Video", family_tree_id: 57, user_id: 57, media_id: 118, media_type: "Video", created_at: "2015-03-09 20:57:19", updated_at: "2015-03-09 20:57:19", circa: nil, is_comment: nil> 
[43] pry(main)> n.user_tags 
    ActsAsTaggableOn::Tag Load (0.3ms) SELECT "tags".* FROM "tags" INNER JOIN "taggings" ON "tags"."id" = "taggings"."tag_id" WHERE "taggings"."taggable_id" = $1 AND "taggings"."taggable_type" = $2 AND "taggings"."context" = 'user_tags' [["taggable_id", 6], ["taggable_type", "Node"]] 
=> [#<ActsAsTaggableOn::Tag id: 6, name: "[email protected]", taggings_count: 1>, #<ActsAsTaggableOn::Tag id: 4, name: "[email protected]", taggings_count: 1>] 

То, что я хотел бы сделать, это создать scope на моей Node модели, чтобы сопоставить только те узлы, которые имеют user_tags. то есть где !user_tags.empty?.

Как это сделать?

+0

Вы можете попробовать: scope: no_tags, lambda {where ('user_tags =?', Nil)} 'или' scope: no_tags, lambda {where ("user_tags IS NULL")} ' – Sontya

+0

@Sontya Я попробовал первый и получил эту ошибку:'> Node.where ('user_tags =?', nil) Узел Load (0.9ms) SELECT «узлы». * FROM «nodes» WHERE (user_tags = NULL) PG :: UndefinedColumn: ERROR: столбец «user_tags» не существует LINE 1: SELECT «узлы». * FROM «узлы» WHERE (user_tags = NULL) '. Я также попробовал второй и получил ту же проблему. Я получаю эту ошибку, потому что я пытаюсь использовать ее в командной строке, вместо того, чтобы помещать ее в лямбда в области видимости? – marcamillion

+0

@Sontya Nope лямбда не проблема. Я просто попробовал это с фактической областью на модели, и я получил ту же ошибку. – marcamillion

ответ

2
scope :with_tags, ->() { joins(:tags).uniq } 

Вы не можете использовать в качестве where тегов хранятся в отдельной таблице, чем модели - вы должны сделать присоединиться к этой другой таблице первым. Теперь прекрасная часть - joins выполняет INNER JOIN, что означает, что она не загрузит модели, у которых нет соответствующих записей в другой таблице. Теперь все, что осталось - это избавиться от дубликатов (если у вас есть модели с n тегами, JOIN вернет эту запись n раз)

+0

Ahhh ... гений. Это работает. Кто бы хотел, чтобы «присоединяется» работает и к виртуальным атрибутам. Это kewl! Спасибо большое Мэн! – marcamillion

+0

awesome. Nice info – Sontya

+0

'tags' не является виртуальным атрибутом - это ассоциация. – BroiSatse