parent 具有多对多关系中的所有 children 组
parent has all of children group in many to many relation
我不太确定正确的术语,所以找不到任何帮助。
使用 Rails 4 我通过 film_tags 在 Film 和 Tag 之间建立了多对多关系。我只想将电影的范围限定为 return 包含一组标签的电影。例如动作和喜剧都是标签,我想搜索同时具有这两个标签的电影。目前我的系统不小心进行了 'or' 搜索,因此它 return 搜索了所有有动作片或喜剧片的电影:
电影:
scope :includes_tags, ->(tags) {joins(:film_tag).merge(FilmTag.tags(tags))}
电影标签:
scope :tags, ->(tags) {where(['film_tags.tag_id IN (?)',tags.map(&:id)])}
是否可以通过这两个标签进行过滤,以便我可以在之后继续链接作用域?
您可以使用 group
和 having
语句来构建您的作用域(未经测试):
class Film < ActiveRecord::Base
scope :includes_tags, ->(tags) do
joins(:film_tags).merge(FilmTag.tags(tags))
.group("films.id")
.having("count(film_tags.id) = ?", tags.size)
end
end
如果 Tag
有一个名为 name
的属性,您可以像这样重构代码以获得更好的性能和可读性:
class FilmTag < ActiveRecord::Base
# remove the .tags scope
end
class Film < ActiveRecord::Base
has_many :film_tags
has_many :tags, through: :film_tags
scope :with_all_tag_names, ->(tag_names) do
joins(film_tags: :tags)
.where(tags: { name: tag_names })
.group("films.id")
.having("count(tags.name) = ?", tag_names.size)
end
end
我不太确定正确的术语,所以找不到任何帮助。
使用 Rails 4 我通过 film_tags 在 Film 和 Tag 之间建立了多对多关系。我只想将电影的范围限定为 return 包含一组标签的电影。例如动作和喜剧都是标签,我想搜索同时具有这两个标签的电影。目前我的系统不小心进行了 'or' 搜索,因此它 return 搜索了所有有动作片或喜剧片的电影:
电影:
scope :includes_tags, ->(tags) {joins(:film_tag).merge(FilmTag.tags(tags))}
电影标签:
scope :tags, ->(tags) {where(['film_tags.tag_id IN (?)',tags.map(&:id)])}
是否可以通过这两个标签进行过滤,以便我可以在之后继续链接作用域?
您可以使用 group
和 having
语句来构建您的作用域(未经测试):
class Film < ActiveRecord::Base
scope :includes_tags, ->(tags) do
joins(:film_tags).merge(FilmTag.tags(tags))
.group("films.id")
.having("count(film_tags.id) = ?", tags.size)
end
end
如果 Tag
有一个名为 name
的属性,您可以像这样重构代码以获得更好的性能和可读性:
class FilmTag < ActiveRecord::Base
# remove the .tags scope
end
class Film < ActiveRecord::Base
has_many :film_tags
has_many :tags, through: :film_tags
scope :with_all_tag_names, ->(tag_names) do
joins(film_tags: :tags)
.where(tags: { name: tag_names })
.group("films.id")
.having("count(tags.name) = ?", tag_names.size)
end
end