|
|
|
@@ -84,7 +84,7 @@ class PostsController < ApplicationController |
|
|
|
title = params[:title].presence |
|
|
|
url = params[:url] |
|
|
|
thumbnail = params[:thumbnail] |
|
|
|
tag_names = params[:tags].to_s.split(' ') |
|
|
|
tag_names = params[:tags].to_s.split |
|
|
|
original_created_from = params[:original_created_from] |
|
|
|
original_created_before = params[:original_created_before] |
|
|
|
|
|
|
|
@@ -125,7 +125,7 @@ class PostsController < ApplicationController |
|
|
|
return head :forbidden unless current_user.gte_member? |
|
|
|
|
|
|
|
title = params[:title].presence |
|
|
|
tag_names = params[:tags].to_s.split(' ') |
|
|
|
tag_names = params[:tags].to_s.split |
|
|
|
original_created_from = params[:original_created_from] |
|
|
|
original_created_before = params[:original_created_before] |
|
|
|
|
|
|
|
@@ -192,7 +192,7 @@ class PostsController < ApplicationController |
|
|
|
private |
|
|
|
|
|
|
|
def filtered_posts |
|
|
|
tag_names = params[:tags].to_s.split(' ') |
|
|
|
tag_names = params[:tags].to_s.split |
|
|
|
match_type = params[:match] |
|
|
|
if tag_names.present? |
|
|
|
filter_posts_by_tags(tag_names, match_type) |
|
|
|
@@ -202,19 +202,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 |
|
|
|
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 |
|
|
|
posts.where(tag_names: { name: tag_names }) |
|
|
|
.group('posts.id') |
|
|
|
.having('COUNT(DISTINCT tag_names.id) = ?', tag_names.uniq.size) |
|
|
|
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? |
|
|
|
|