OR 検索と NOT 検索(#68) (#286)
Merge remote-tracking branch 'origin/main' into feature/068 #68 テスト・ケース作成 #68 #68 まづは NOT に対応 Co-authored-by: miteruzo <miteruzo@naver.com> Reviewed-on: #286
This commit was merged in pull request #286.
This commit is contained in:
@@ -245,19 +245,41 @@ class PostsController < ApplicationController
|
||||
end
|
||||
|
||||
def filter_posts_by_tags tag_names, match_type
|
||||
tag_names = TagName.canonicalise(tag_names)
|
||||
literals = tag_names.map do |raw_name|
|
||||
{ name: TagName.canonicalise(raw_name.sub(/\Anot:/i, '')).first,
|
||||
negative: raw_name.downcase.start_with?('not:') }
|
||||
end
|
||||
|
||||
posts = Post.joins(tags: :tag_name)
|
||||
return Post.all if literals.empty?
|
||||
|
||||
if match_type == 'any'
|
||||
posts.where(tag_names: { name: tag_names }).distinct
|
||||
literals.reduce(Post.none) do |posts, literal|
|
||||
posts.or(tag_literal_relation(literal[:name], negative: literal[:negative]))
|
||||
end
|
||||
else
|
||||
posts.where(tag_names: { name: tag_names })
|
||||
.group('posts.id')
|
||||
.having('COUNT(DISTINCT tag_names.id) = ?', tag_names.uniq.size)
|
||||
literals.reduce(Post.all) do |posts, literal|
|
||||
ids = tagged_post_ids_for(literal[:name])
|
||||
if literal[:negative]
|
||||
posts.where.not(id: ids)
|
||||
else
|
||||
posts.where(id: ids)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def tag_literal_relation name, negative:
|
||||
ids = tagged_post_ids_for(name)
|
||||
if negative
|
||||
Post.where.not(id: ids)
|
||||
else
|
||||
Post.where(id: ids)
|
||||
end
|
||||
end
|
||||
|
||||
def tagged_post_ids_for(name) =
|
||||
Post.joins(tags: :tag_name).where(tag_names: { name: }).select(:id)
|
||||
|
||||
def sync_post_tags! post, desired_tags
|
||||
desired_tags.each do |t|
|
||||
t.save! if t.new_record?
|
||||
|
||||
@@ -17,8 +17,7 @@ class TagsController < ApplicationController
|
||||
end
|
||||
|
||||
def autocomplete
|
||||
q = params[:q].to_s.strip
|
||||
return render json: [] if q.blank?
|
||||
q = params[:q].to_s.strip.sub(/\Anot:/i, '')
|
||||
|
||||
with_nico = bool?(:nico, default: true)
|
||||
present_only = bool?(:present, default: true)
|
||||
|
||||
Reference in New Issue
Block a user