gpt4 book ai didi

sql - Rails HABTM 查询——带有所有标签的文章

转载 作者:行者123 更新时间:2023-11-29 13:31:45 25 4
gpt4 key购买 nike

我在我的应用程序 (Rails 3) 中创建了两个表:

def change
create_table :articles do |t|
t.string :name
t.text :content
t.timestamps
end

create_table :tags do |t|
t.string :name
t.timestamps
end

create_table :articles_tags do |t|
t.belongs_to :article
t.belongs_to :tag
end

add_index :articles_tags, :article_id
add_index :articles_tags, :tag_id
end

我希望能够通过两种方式搜索基于标签的文章:

  1. 带有任何给定标签的文章(union)
  2. 具有所有给定标签(交集)的文章

所以,换句话说,让我可以这样做的东西:

tag1 = Tag.create(name: 'tag1')
tag2 = Tag.create(name: 'tag2')

a = Article.create; a.tags << tag1
b = Article.create; b.tags += [tag1, tag2]

Article.tagged_with_any(['tag1', 'tag2'])
# => [a,b]

Article.tagged_with_all(['tag1', 'tag2'])
# => [b]

第一个相对容易。我刚刚在 Article 上做了这个范围:

scope :tagged_with_any, lambda { |tag_names|
joins(:tags).where('tags.name IN (?)', tag_names)
}

问题是第二个。我不知道如何在 ActiveRecord 或 SQL 中执行此操作。

我想我也许可以像这样做一些恶心的事情:

scope :tagged_with_all, lambda { |tag_names|
new_scope = self

# Want to allow for single string query args
Array(tag_names).each do |name|
new_scope = new_scope.tagged_with_any(name)
end
new_scope
}

但我敢打赌那是非常低效的,而且闻起来很臭。关于如何正确执行此操作的任何想法?

最佳答案

正如您所说,该范围非常低效(而且丑陋)。

尝试这样的事情:

def self.tagged_with_all(tags)
joins(:tags).where('tags.name IN (?)', tags).group('article_id').having('count(*)=?', tags.count).select('article_id')
end

关键在 having 子句中。您可能还想看看 SQL 表之间的除法操作。

关于sql - Rails HABTM 查询——带有所有标签的文章,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21618890/

25 4 0