favgroups: convert post_ids from string to array.
This commit is contained in:
@@ -1,15 +1,13 @@
|
||||
require 'ostruct'
|
||||
|
||||
class FavoriteGroup < ApplicationRecord
|
||||
validates_uniqueness_of :name, :case_sensitive => false, :scope => :creator_id
|
||||
validates_format_of :name, :with => /\A[^,]+\Z/, :message => "cannot have commas"
|
||||
belongs_to_creator
|
||||
before_validation :normalize_post_ids
|
||||
before_validation :normalize_name
|
||||
before_validation :strip_name
|
||||
validate :creator_can_create_favorite_groups, :on => :create
|
||||
validate :validate_number_of_posts
|
||||
before_save :update_post_count
|
||||
|
||||
array_attribute :post_ids, parse: /\d+/, cast: :to_i
|
||||
|
||||
module SearchMethods
|
||||
def for_creator(user_id)
|
||||
@@ -17,8 +15,7 @@ class FavoriteGroup < ApplicationRecord
|
||||
end
|
||||
|
||||
def for_post(post_id)
|
||||
regexp = "(^#{post_id}$|^#{post_id} | #{post_id}$| #{post_id} )"
|
||||
where("favorite_groups.post_ids ~ ?", regexp)
|
||||
where_array_includes_any(:post_ids, [post_id])
|
||||
end
|
||||
|
||||
def named(name)
|
||||
@@ -47,7 +44,7 @@ class FavoriteGroup < ApplicationRecord
|
||||
|
||||
def search(params)
|
||||
q = super
|
||||
q = q.search_attributes(params, :name, :is_public, :post_count)
|
||||
q = q.search_attributes(params, :name, :is_public, :post_ids)
|
||||
|
||||
if params[:creator_id].present?
|
||||
user = User.find(params[:creator_id])
|
||||
@@ -91,15 +88,11 @@ class FavoriteGroup < ApplicationRecord
|
||||
end
|
||||
|
||||
def validate_number_of_posts
|
||||
if post_id_array.size > 10_000
|
||||
self.errors.add(:base, "Favorite groups can have up to 10,000 posts each")
|
||||
if post_count > 10_000
|
||||
errors[:base] << "Favorite groups can have up to 10,000 posts each"
|
||||
end
|
||||
end
|
||||
|
||||
def normalize_post_ids
|
||||
self.post_ids = post_ids.scan(/\d+/).uniq.join(" ")
|
||||
end
|
||||
|
||||
def self.normalize_name(name)
|
||||
name.gsub(/[[:space:]]+/, "_")
|
||||
end
|
||||
@@ -126,94 +119,49 @@ class FavoriteGroup < ApplicationRecord
|
||||
name.tr("_", " ")
|
||||
end
|
||||
|
||||
def posts(options = {})
|
||||
offset = options[:offset] || 0
|
||||
limit = options[:limit] || Danbooru.config.posts_per_page
|
||||
slice = post_id_array.slice(offset, limit)
|
||||
if slice&.any?
|
||||
slice.map do |id|
|
||||
Post.find(id)
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
# swallow
|
||||
end.compact
|
||||
else
|
||||
[]
|
||||
end
|
||||
def posts
|
||||
favgroup_posts = FavoriteGroup.where(id: id).joins("CROSS JOIN unnest(favorite_groups.post_ids) WITH ORDINALITY AS row(post_id, favgroup_index)").select(:post_id, :favgroup_index)
|
||||
posts = Post.joins("JOIN (#{favgroup_posts.to_sql}) favgroup_posts ON favgroup_posts.post_id = posts.id").order("favgroup_posts.favgroup_index ASC")
|
||||
end
|
||||
|
||||
def post_id_array
|
||||
@post_id_array ||= post_ids.scan(/\d+/).map(&:to_i)
|
||||
end
|
||||
|
||||
def post_id_array=(array)
|
||||
self.post_ids = array.join(" ")
|
||||
clear_post_id_array
|
||||
end
|
||||
|
||||
def post_id_array_was
|
||||
@post_id_array_was ||= post_ids_was.scan(/\d+/).map(&:to_i)
|
||||
end
|
||||
|
||||
def clear_post_id_array
|
||||
@post_id_array = nil
|
||||
@post_id_array_was = nil
|
||||
end
|
||||
|
||||
def update_post_count
|
||||
normalize_post_ids
|
||||
clear_post_id_array
|
||||
self.post_count = post_id_array.size
|
||||
end
|
||||
|
||||
def add!(post_id)
|
||||
def add!(post)
|
||||
with_lock do
|
||||
post_id = post_id.id if post_id.is_a?(Post)
|
||||
return if contains?(post_id)
|
||||
|
||||
clear_post_id_array
|
||||
update(post_ids: add_number_to_string(post_id, post_ids))
|
||||
return if contains?(post.id)
|
||||
update!(post_ids: post_ids + [post.id])
|
||||
end
|
||||
end
|
||||
|
||||
def remove!(post_id)
|
||||
def remove!(post)
|
||||
with_lock do
|
||||
post_id = post_id.id if post_id.is_a?(Post)
|
||||
return unless contains?(post_id)
|
||||
|
||||
clear_post_id_array
|
||||
update(post_ids: remove_number_from_string(post_id, post_ids))
|
||||
return unless contains?(post.id)
|
||||
update!(post_ids: post_ids - [post.id])
|
||||
end
|
||||
end
|
||||
|
||||
def add_number_to_string(number, string)
|
||||
"#{string} #{number}"
|
||||
def post_count
|
||||
post_ids.size
|
||||
end
|
||||
|
||||
def remove_number_from_string(number, string)
|
||||
string.gsub(/(?:\A| )#{number}(?:\Z| )/, " ")
|
||||
def first_post?(post_id)
|
||||
post_id == post_ids.first
|
||||
end
|
||||
|
||||
def neighbors(post)
|
||||
@neighbor_posts ||= begin
|
||||
post_ids =~ /\A#{post.id} (\d+)|(\d+) #{post.id} (\d+)|(\d+) #{post.id}\Z/
|
||||
|
||||
if $2 && $3
|
||||
OpenStruct.new(:previous => $2.to_i, :next => $3.to_i)
|
||||
elsif $1
|
||||
OpenStruct.new(:next => $1.to_i)
|
||||
elsif $4
|
||||
OpenStruct.new(:previous => $4.to_i)
|
||||
else
|
||||
OpenStruct.new
|
||||
end
|
||||
end
|
||||
def last_post?(post_id)
|
||||
post_id == post_ids.last
|
||||
end
|
||||
|
||||
def reload(options = {})
|
||||
super
|
||||
@neighbor_posts = nil
|
||||
clear_post_id_array
|
||||
self
|
||||
def previous_post_id(post_id)
|
||||
return nil if first_post?(post_id) || !contains?(post_id)
|
||||
|
||||
n = post_ids.index(post_id) - 1
|
||||
post_ids[n]
|
||||
end
|
||||
|
||||
def next_post_id(post_id)
|
||||
return nil if last_post?(post_id) || !contains?(post_id)
|
||||
|
||||
n = post_ids.index(post_id) + 1
|
||||
post_ids[n]
|
||||
end
|
||||
|
||||
def last_page
|
||||
@@ -221,7 +169,7 @@ class FavoriteGroup < ApplicationRecord
|
||||
end
|
||||
|
||||
def contains?(post_id)
|
||||
post_ids =~ /(?:\A| )#{post_id}(?:\Z| )/
|
||||
post_ids.include?(post_id)
|
||||
end
|
||||
|
||||
def editable_by?(user)
|
||||
|
||||
@@ -34,15 +34,6 @@ class Pool < ApplicationRecord
|
||||
where("pools.category = ?", "collection")
|
||||
end
|
||||
|
||||
def series_first
|
||||
order(Arel.sql("(case pools.category when 'series' then 0 else 1 end), pools.name"))
|
||||
end
|
||||
|
||||
def selected_first(current_pool_id)
|
||||
return all if current_pool_id.blank?
|
||||
reorder(Arel.sql("(case pools.id when #{current_pool_id.to_i} then 0 else 1 end), pools.name"))
|
||||
end
|
||||
|
||||
def name_matches(name)
|
||||
name = normalize_name_for_search(name)
|
||||
name = "*#{name}*" unless name =~ /\*/
|
||||
|
||||
@@ -822,19 +822,19 @@ class Post < ApplicationRecord
|
||||
|
||||
when /^-favgroup:(\d+)$/i
|
||||
favgroup = FavoriteGroup.where("id = ?", $1.to_i).for_creator(CurrentUser.user.id).first
|
||||
favgroup&.remove!(id)
|
||||
favgroup&.remove!(self)
|
||||
|
||||
when /^-favgroup:(.+)$/i
|
||||
favgroup = FavoriteGroup.named($1).for_creator(CurrentUser.user.id).first
|
||||
favgroup&.remove!(id)
|
||||
favgroup&.remove!(self)
|
||||
|
||||
when /^favgroup:(\d+)$/i
|
||||
favgroup = FavoriteGroup.where("id = ?", $1.to_i).for_creator(CurrentUser.user.id).first
|
||||
favgroup&.add!(id)
|
||||
favgroup&.add!(self)
|
||||
|
||||
when /^favgroup:(.+)$/i
|
||||
favgroup = FavoriteGroup.named($1).for_creator(CurrentUser.user.id).first
|
||||
favgroup&.add!(id)
|
||||
favgroup&.add!(self)
|
||||
|
||||
end
|
||||
end
|
||||
@@ -962,21 +962,8 @@ class Post < ApplicationRecord
|
||||
ordered_users
|
||||
end
|
||||
|
||||
def favorite_groups(active_id = nil)
|
||||
@favorite_groups ||= begin
|
||||
groups = []
|
||||
|
||||
if active_id.present?
|
||||
active_group = FavoriteGroup.where(:id => active_id.to_i).first
|
||||
groups << active_group if active_group&.contains?(self.id)
|
||||
end
|
||||
|
||||
groups += CurrentUser.user.favorite_groups.select do |favgroup|
|
||||
favgroup.contains?(self.id)
|
||||
end
|
||||
|
||||
groups.uniq
|
||||
end
|
||||
def favorite_groups
|
||||
FavoriteGroup.for_post(id)
|
||||
end
|
||||
|
||||
def remove_from_favorites
|
||||
@@ -988,7 +975,7 @@ class Post < ApplicationRecord
|
||||
|
||||
def remove_from_fav_groups
|
||||
FavoriteGroup.for_post(id).find_each do |favgroup|
|
||||
favgroup.remove!(id)
|
||||
favgroup.remove!(self)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1008,7 +995,7 @@ class Post < ApplicationRecord
|
||||
|
||||
module PoolMethods
|
||||
def pools
|
||||
Pool.where("pools.post_ids && array[?]", id).series_first
|
||||
Pool.where("pools.post_ids && array[?]", id)
|
||||
end
|
||||
|
||||
def has_active_pools?
|
||||
@@ -1804,7 +1791,6 @@ class Post < ApplicationRecord
|
||||
super
|
||||
reset_tag_array_cache
|
||||
@pools = nil
|
||||
@favorite_groups = nil
|
||||
@tag_categories = nil
|
||||
@typed_tags = nil
|
||||
self
|
||||
|
||||
@@ -602,7 +602,7 @@ class Tag < ApplicationRecord
|
||||
end
|
||||
|
||||
q[:favgroups_neg] ||= []
|
||||
q[:favgroups_neg] << favgroup_id
|
||||
q[:favgroups_neg] << favgroup
|
||||
|
||||
when "favgroup"
|
||||
favgroup_id = FavoriteGroup.name_to_id(g2)
|
||||
@@ -613,7 +613,7 @@ class Tag < ApplicationRecord
|
||||
end
|
||||
|
||||
q[:favgroups] ||= []
|
||||
q[:favgroups] << favgroup_id
|
||||
q[:favgroups] << favgroup
|
||||
|
||||
when "-fav"
|
||||
favuser = User.find_by_name(g2)
|
||||
|
||||
Reference in New Issue
Block a user