favgroups: convert post_ids from string to array.

This commit is contained in:
evazion
2020-01-14 23:33:55 -06:00
parent eecd9a183d
commit ab325c5d2b
25 changed files with 141 additions and 288 deletions

View File

@@ -8,9 +8,12 @@ class FavoriteGroupsController < ApplicationController
end end
def show def show
limit = params[:limit].presence || CurrentUser.user.per_page
@current_item = @favorite_group = FavoriteGroup.find(params[:id]) @current_item = @favorite_group = FavoriteGroup.find(params[:id])
check_read_privilege(@favorite_group) check_read_privilege(@favorite_group)
@post_set = PostSets::FavoriteGroup.new(@favorite_group, params[:page]) @posts = @favorite_group.posts.paginate(params[:page], limit: limit, count: @favorite_group.post_count)
respond_with(@favorite_group) respond_with(@favorite_group)
end end
@@ -52,7 +55,7 @@ class FavoriteGroupsController < ApplicationController
@favorite_group = FavoriteGroup.find(params[:id]) @favorite_group = FavoriteGroup.find(params[:id])
check_write_privilege(@favorite_group) check_write_privilege(@favorite_group)
@post = Post.find(params[:post_id]) @post = Post.find(params[:post_id])
@favorite_group.add!(@post.id) @favorite_group.add!(@post)
end end
private private
@@ -66,6 +69,6 @@ class FavoriteGroupsController < ApplicationController
end end
def favgroup_params def favgroup_params
params.fetch(:favorite_group, {}).permit(%i[name post_ids is_public], post_id_array: []) params.fetch(:favorite_group, {}).permit(%i[name post_ids post_ids_string is_public], post_ids: [])
end end
end end

View File

@@ -193,7 +193,7 @@ Post.nav_prev = function(e) {
} else if ($(".paginator a[rel~=prev]").length) { } else if ($(".paginator a[rel~=prev]").length) {
location.href = $("a[rel~=prev]").attr("href"); location.href = $("a[rel~=prev]").attr("href");
} else { } else {
href = $("#pool-nav li.pool-selected-true a[rel~=prev], #favgroup-nav a.active[rel~=prev]").attr("href"); href = $("#pool-nav li[data-selected=true] a[rel=prev], #favgroup-nav li[data-selected=true] a[rel=prev]").attr("href");
if (href) { if (href) {
location.href = href; location.href = href;
} }
@@ -211,7 +211,7 @@ Post.nav_next = function(e) {
} else if ($(".paginator a[rel~=next]").length) { } else if ($(".paginator a[rel~=next]").length) {
location.href = $(".paginator a[rel~=next]").attr("href"); location.href = $(".paginator a[rel~=next]").attr("href");
} else { } else {
href = $("#pool-nav li.pool-selected-true a[rel~=next], #favgroup-nav a.active[rel~=next]").attr("href"); href = $("#pool-nav li[data-selected=true] a[rel=next], #favgroup-nav li[data-selected=true] a[rel=next]").attr("href");
if (href) { if (href) {
location.href = href; location.href = href;
} }

View File

@@ -316,10 +316,6 @@ div#c-posts {
} }
div#a-show { div#a-show {
.active, .pool-selected-true {
font-weight: bold;
}
#post-info-source { #post-info-source {
word-break: break-all; word-break: break-all;
} }
@@ -377,6 +373,10 @@ div#c-posts {
text-align: center; text-align: center;
padding: 0 5.5em; padding: 0 5.5em;
&[data-selected="true"] {
font-weight: bold;
}
.prev { .prev {
position: absolute; position: absolute;
left: 2em; left: 2em;

View File

@@ -450,24 +450,12 @@ class PostQueryBuilder
relation = relation.joins("JOIN (#{pool_posts.to_sql}) pool_posts ON pool_posts.post_id = posts.id").order("pool_posts.pool_index ASC") relation = relation.joins("JOIN (#{pool_posts.to_sql}) pool_posts ON pool_posts.post_id = posts.id").order("pool_posts.pool_index ASC")
end end
if q[:favgroups_neg].present? q[:favgroups_neg].to_a.each do |favgroup|
q[:favgroups_neg].each do |favgroup_rec| relation = relation.where.not("posts.id": favgroup.post_ids)
favgroup_id = favgroup_rec.to_i
favgroup = FavoriteGroup.where("favorite_groups.id = ?", favgroup_id).first
if favgroup
relation = relation.where.not("posts.id": favgroup.post_id_array)
end
end
end end
if q[:favgroups].present? q[:favgroups].to_a.each do |favgroup|
q[:favgroups].each do |favgroup_rec| relation = relation.where("posts.id": favgroup.post_ids)
favgroup_id = favgroup_rec.to_i
favgroup = FavoriteGroup.where("favorite_groups.id = ?", favgroup_id).first
if favgroup
relation = relation.where("posts.id": favgroup.post_id_array)
end
end
end end
if q[:upvote].present? if q[:upvote].present?

View File

@@ -1,7 +0,0 @@
module PostSets
class FavoriteGroup < PostSets::Pool
def presenter
@presenter ||= PostSetPresenters::FavoriteGroup.new(self)
end
end
end

View File

@@ -1,60 +0,0 @@
module PostSets
class Pool < PostSets::Base
module ActiveRecordExtension
attr_accessor :total_pages, :current_page
end
attr_reader :pool, :page
def initialize(pool, page = 1)
@pool = pool
@page = page
end
def offset
(current_page - 1) * limit
end
def limit
CurrentUser.user.per_page
end
def tag_array
["pool:#{pool.id}"]
end
def posts
@posts ||= begin
x = pool.posts(:offset => offset, :limit => limit)
x.extend(ActiveRecordExtension)
x.total_pages = total_pages
x.current_page = current_page
x
end
end
def tag_string
tag_array.join("")
end
def humanized_tag_string
"pool:#{pool.pretty_name}"
end
def presenter
@presenter ||= PostSetPresenters::Pool.new(self)
end
def total_pages
(pool.post_count.to_f / limit).ceil
end
def size
posts.size
end
def current_page
[page.to_i, 1].max
end
end
end

View File

@@ -1,15 +1,13 @@
require 'ostruct'
class FavoriteGroup < ApplicationRecord class FavoriteGroup < ApplicationRecord
validates_uniqueness_of :name, :case_sensitive => false, :scope => :creator_id validates_uniqueness_of :name, :case_sensitive => false, :scope => :creator_id
validates_format_of :name, :with => /\A[^,]+\Z/, :message => "cannot have commas" validates_format_of :name, :with => /\A[^,]+\Z/, :message => "cannot have commas"
belongs_to_creator belongs_to_creator
before_validation :normalize_post_ids
before_validation :normalize_name before_validation :normalize_name
before_validation :strip_name before_validation :strip_name
validate :creator_can_create_favorite_groups, :on => :create validate :creator_can_create_favorite_groups, :on => :create
validate :validate_number_of_posts validate :validate_number_of_posts
before_save :update_post_count
array_attribute :post_ids, parse: /\d+/, cast: :to_i
module SearchMethods module SearchMethods
def for_creator(user_id) def for_creator(user_id)
@@ -17,8 +15,7 @@ class FavoriteGroup < ApplicationRecord
end end
def for_post(post_id) def for_post(post_id)
regexp = "(^#{post_id}$|^#{post_id} | #{post_id}$| #{post_id} )" where_array_includes_any(:post_ids, [post_id])
where("favorite_groups.post_ids ~ ?", regexp)
end end
def named(name) def named(name)
@@ -47,7 +44,7 @@ class FavoriteGroup < ApplicationRecord
def search(params) def search(params)
q = super 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? if params[:creator_id].present?
user = User.find(params[:creator_id]) user = User.find(params[:creator_id])
@@ -91,15 +88,11 @@ class FavoriteGroup < ApplicationRecord
end end
def validate_number_of_posts def validate_number_of_posts
if post_id_array.size > 10_000 if post_count > 10_000
self.errors.add(:base, "Favorite groups can have up to 10,000 posts each") errors[:base] << "Favorite groups can have up to 10,000 posts each"
end end
end end
def normalize_post_ids
self.post_ids = post_ids.scan(/\d+/).uniq.join(" ")
end
def self.normalize_name(name) def self.normalize_name(name)
name.gsub(/[[:space:]]+/, "_") name.gsub(/[[:space:]]+/, "_")
end end
@@ -126,94 +119,49 @@ class FavoriteGroup < ApplicationRecord
name.tr("_", " ") name.tr("_", " ")
end end
def posts(options = {}) def posts
offset = options[:offset] || 0 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)
limit = options[:limit] || Danbooru.config.posts_per_page posts = Post.joins("JOIN (#{favgroup_posts.to_sql}) favgroup_posts ON favgroup_posts.post_id = posts.id").order("favgroup_posts.favgroup_index ASC")
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
end end
def post_id_array def add!(post)
@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)
with_lock do with_lock do
post_id = post_id.id if post_id.is_a?(Post) return if contains?(post.id)
return if contains?(post_id) update!(post_ids: post_ids + [post.id])
clear_post_id_array
update(post_ids: add_number_to_string(post_id, post_ids))
end end
end end
def remove!(post_id) def remove!(post)
with_lock do with_lock do
post_id = post_id.id if post_id.is_a?(Post) return unless contains?(post.id)
return unless contains?(post_id) update!(post_ids: post_ids - [post.id])
clear_post_id_array
update(post_ids: remove_number_from_string(post_id, post_ids))
end end
end end
def add_number_to_string(number, string) def post_count
"#{string} #{number}" post_ids.size
end end
def remove_number_from_string(number, string) def first_post?(post_id)
string.gsub(/(?:\A| )#{number}(?:\Z| )/, " ") post_id == post_ids.first
end end
def neighbors(post) def last_post?(post_id)
@neighbor_posts ||= begin post_id == post_ids.last
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
end end
def reload(options = {}) def previous_post_id(post_id)
super return nil if first_post?(post_id) || !contains?(post_id)
@neighbor_posts = nil
clear_post_id_array n = post_ids.index(post_id) - 1
self 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 end
def last_page def last_page
@@ -221,7 +169,7 @@ class FavoriteGroup < ApplicationRecord
end end
def contains?(post_id) def contains?(post_id)
post_ids =~ /(?:\A| )#{post_id}(?:\Z| )/ post_ids.include?(post_id)
end end
def editable_by?(user) def editable_by?(user)

View File

@@ -34,15 +34,6 @@ class Pool < ApplicationRecord
where("pools.category = ?", "collection") where("pools.category = ?", "collection")
end 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) def name_matches(name)
name = normalize_name_for_search(name) name = normalize_name_for_search(name)
name = "*#{name}*" unless name =~ /\*/ name = "*#{name}*" unless name =~ /\*/

View File

@@ -822,19 +822,19 @@ class Post < ApplicationRecord
when /^-favgroup:(\d+)$/i when /^-favgroup:(\d+)$/i
favgroup = FavoriteGroup.where("id = ?", $1.to_i).for_creator(CurrentUser.user.id).first favgroup = FavoriteGroup.where("id = ?", $1.to_i).for_creator(CurrentUser.user.id).first
favgroup&.remove!(id) favgroup&.remove!(self)
when /^-favgroup:(.+)$/i when /^-favgroup:(.+)$/i
favgroup = FavoriteGroup.named($1).for_creator(CurrentUser.user.id).first favgroup = FavoriteGroup.named($1).for_creator(CurrentUser.user.id).first
favgroup&.remove!(id) favgroup&.remove!(self)
when /^favgroup:(\d+)$/i when /^favgroup:(\d+)$/i
favgroup = FavoriteGroup.where("id = ?", $1.to_i).for_creator(CurrentUser.user.id).first favgroup = FavoriteGroup.where("id = ?", $1.to_i).for_creator(CurrentUser.user.id).first
favgroup&.add!(id) favgroup&.add!(self)
when /^favgroup:(.+)$/i when /^favgroup:(.+)$/i
favgroup = FavoriteGroup.named($1).for_creator(CurrentUser.user.id).first favgroup = FavoriteGroup.named($1).for_creator(CurrentUser.user.id).first
favgroup&.add!(id) favgroup&.add!(self)
end end
end end
@@ -962,21 +962,8 @@ class Post < ApplicationRecord
ordered_users ordered_users
end end
def favorite_groups(active_id = nil) def favorite_groups
@favorite_groups ||= begin FavoriteGroup.for_post(id)
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
end end
def remove_from_favorites def remove_from_favorites
@@ -988,7 +975,7 @@ class Post < ApplicationRecord
def remove_from_fav_groups def remove_from_fav_groups
FavoriteGroup.for_post(id).find_each do |favgroup| FavoriteGroup.for_post(id).find_each do |favgroup|
favgroup.remove!(id) favgroup.remove!(self)
end end
end end
end end
@@ -1008,7 +995,7 @@ class Post < ApplicationRecord
module PoolMethods module PoolMethods
def pools def pools
Pool.where("pools.post_ids && array[?]", id).series_first Pool.where("pools.post_ids && array[?]", id)
end end
def has_active_pools? def has_active_pools?
@@ -1804,7 +1791,6 @@ class Post < ApplicationRecord
super super
reset_tag_array_cache reset_tag_array_cache
@pools = nil @pools = nil
@favorite_groups = nil
@tag_categories = nil @tag_categories = nil
@typed_tags = nil @typed_tags = nil
self self

View File

@@ -602,7 +602,7 @@ class Tag < ApplicationRecord
end end
q[:favgroups_neg] ||= [] q[:favgroups_neg] ||= []
q[:favgroups_neg] << favgroup_id q[:favgroups_neg] << favgroup
when "favgroup" when "favgroup"
favgroup_id = FavoriteGroup.name_to_id(g2) favgroup_id = FavoriteGroup.name_to_id(g2)
@@ -613,7 +613,7 @@ class Tag < ApplicationRecord
end end
q[:favgroups] ||= [] q[:favgroups] ||= []
q[:favgroups] << favgroup_id q[:favgroups] << favgroup
when "-fav" when "-fav"
favuser = User.find_by_name(g2) favuser = User.find_by_name(g2)

View File

@@ -173,7 +173,7 @@ class PostPresenter < Presenter
end end
def has_nav_links?(template) def has_nav_links?(template)
has_sequential_navigation?(template.params) || @post.pools.undeleted.any? || @post.favorite_groups(active_id = template.params[:favgroup_id]).any? has_sequential_navigation?(template.params) || @post.pools.undeleted.any? || CurrentUser.favorite_groups.for_post(@post.id).any?
end end
def has_sequential_navigation?(params) def has_sequential_navigation?(params)

View File

@@ -1,17 +0,0 @@
module PostSetPresenters
class FavoriteGroup < PostSetPresenters::Pool
def post_previews_html(template)
html = ""
if posts.empty?
return template.render("post_sets/blank")
end
posts.each do |post|
html << PostPresenter.preview(post, :favgroup_id => post_set.pool.id, :show_deleted => true)
end
html.html_safe
end
end
end

View File

@@ -1,24 +0,0 @@
module PostSetPresenters
class Pool < Base
attr_reader :post_set
delegate :posts, :to => :post_set
def initialize(post_set)
@post_set = post_set
end
def post_previews_html(template)
html = ""
if posts.empty?
return template.render("post_sets/blank")
end
posts.each do |post|
html << PostPresenter.preview(post, :pool_id => post_set.pool.id)
end
html.html_safe
end
end
end

View File

@@ -6,8 +6,8 @@
<%= render "posts/partials/common/inline_blacklist" %> <%= render "posts/partials/common/inline_blacklist" %>
<ul id="sortable"> <ul id="sortable">
<% @favorite_group.posts(:limit => 1_000).each do |post| %> <% @favorite_group.posts.limit(1_000).each do |post| %>
<li class="ui-state-default" id="favorite_group[post_id_array]_<%= post.id %>"> <li class="ui-state-default" id="favorite_group[post_ids]_<%= post.id %>">
<%= PostPresenter.preview(post).presence || "Hidden: Post ##{post.id}" %> <%= PostPresenter.preview(post).presence || "Hidden: Post ##{post.id}" %>
</li> </li>
<% end %> <% end %>

View File

@@ -6,7 +6,7 @@
<%= edit_form_for(@favorite_group) do |f| %> <%= edit_form_for(@favorite_group) do |f| %>
<%= f.input :name, :as => :string, :input_html => { :value => @favorite_group.pretty_name } %> <%= f.input :name, :as => :string, :input_html => { :value => @favorite_group.pretty_name } %>
<%= f.input :post_ids, :label => "Posts" %> <%= f.input :post_ids_string, label: "Posts", as: :text %>
<%= f.input :is_public %> <%= f.input :is_public %>
<%= f.button :submit, "Submit" %> <%= f.button :submit, "Submit" %>
<% end %> <% end %>

View File

@@ -6,7 +6,7 @@
<%= edit_form_for(@favorite_group) do |f| %> <%= edit_form_for(@favorite_group) do |f| %>
<%= f.input :name, :as => :string, :required => true %> <%= f.input :name, :as => :string, :required => true %>
<%= f.input :post_ids, :label => "Posts" %> <%= f.input :post_ids_string, :label => "Posts" %>
<%= f.button :submit, "Submit" %> <%= f.button :submit, "Submit" %>
<% end %> <% end %>
</div> </div>

View File

@@ -4,6 +4,7 @@
Favorite Group: Favorite Group:
<%= link_to @favorite_group.pretty_name, posts_path(:tags => "favgroup:#{@favorite_group.id}") %> <%= link_to @favorite_group.pretty_name, posts_path(:tags => "favgroup:#{@favorite_group.id}") %>
</h1> </h1>
Creator: <%= link_to_user @favorite_group.creator %> Creator: <%= link_to_user @favorite_group.creator %>
<br> <br>
<br> <br>
@@ -11,9 +12,13 @@
<%= render "posts/partials/common/inline_blacklist" %> <%= render "posts/partials/common/inline_blacklist" %>
<section> <section>
<%= @post_set.presenter.post_previews_html(self) %> <% if @favorite_group.post_count == 0 %>
<%= render "post_sets/blank" %>
<% else %>
<%= post_previews_html(@posts, favgroup_id: @favorite_group.id) %>
<%= numbered_paginator(@post_set) %> <%= numbered_paginator(@posts) %>
<% end %>
</section> </section>
</div> </div>
</div> </div>

View File

@@ -1,25 +1,34 @@
<div id="favgroup-nav"> <div id="favgroup-nav">
<ul> <ul>
<% post.favorite_groups(active_id=params[:favgroup_id]).each do |favgroup| %> <% favgroups = favgroups.sort_by { |favgroup| [(favgroup.id == params[:favgroup_id].to_i) ? 0 : 1, favgroup.name] } %>
<li> <% favgroups.each do |favgroup| %>
<% klass = "active" if favgroup.id == params[:favgroup_id].to_i %> <% selected = favgroup.id == params[:favgroup_id].to_i %>
<% if favgroup.neighbors(post).previous %> <%= tag.li id: "nav-link-for-favgroup-#{favgroup.id}", "data-selected": selected do %>
<%= link_to("&lsaquo;&thinsp;prev".html_safe, post_path(favgroup.neighbors(post).previous, :favgroup_id => favgroup.id), :rel => "prev", :class => "prev #{klass}") %> <span class="first">
<% else %> <%= link_to_unless favgroup.first_post?(post.id), "«", post_path(favgroup.post_ids.first, favgroup_id: favgroup.id) %>
<span class="prev">&lsaquo;&thinsp;prev</span>
<% end %>
<span class="favgroup-name <%= klass %>">
<%= link_to("Favorite group: #{favgroup.pretty_name}", favorite_group_path(favgroup)) %>
</span> </span>
<% if favgroup.neighbors(post).next %> <% favgroup.previous_post_id(post.id).tap do |previous_post_id| %>
<%= link_to("next&thinsp;&rsaquo;".html_safe, post_path(favgroup.neighbors(post).next, :favgroup_id => favgroup.id), :rel => "next", :class => "next #{klass}") %> <span class="prev">
<% else %> <%= link_to_if previous_post_id, " prev", post_path(previous_post_id.to_i, favgroup_id: favgroup.id), rel: ("prev" if selected) %>
<span class="next">next&thinsp;&rsaquo;</span> </span>
<% end %> <% end %>
</li>
<span class="favgroup-name">
<%= link_to "Favorite group: #{favgroup.pretty_name}", favgroup %>
</span>
<% favgroup.next_post_id(post.id).tap do |next_post_id| %>
<span class="next">
<%= link_to_if next_post_id, "next ", post_path(next_post_id.to_i, favgroup_id: favgroup.id), rel: ("next" if selected) %>
</span>
<% end %>
<span class="last">
<%= link_to_unless favgroup.last_post?(post.id), "»", post_path(favgroup.post_ids.last, favgroup_id: favgroup.id) %>
</span>
<% end %>
<% end %> <% end %>
</ul> </ul>
</div> </div>

View File

@@ -5,11 +5,11 @@
<% end %> <% end %>
<% if post.pools.undeleted.present? %> <% if post.pools.undeleted.present? %>
<%= render "posts/partials/show/pool_list", post: post, pools: post.pools.undeleted.selected_first(params[:pool_id]) %> <%= render "posts/partials/show/pool_list", post: post, pools: post.pools.undeleted %>
<% end %> <% end %>
<% if post.favorite_groups(active_id=params[:favgroup_id]).any? %> <% if CurrentUser.user.favorite_groups.for_post(post.id).present? %>
<%= render "posts/partials/show/favorite_groups", :post => post %> <%= render "posts/partials/show/favorite_groups", post: post, favgroups: CurrentUser.user.favorite_groups.for_post(post.id) %>
<% end %> <% end %>
</div> </div>
<% end %> <% end %>

View File

@@ -1,5 +1,6 @@
<div id="pool-nav"> <div id="pool-nav">
<ul> <ul>
<% pools = pools.sort_by { |pool| [is_pool_selected?(pool) ? 0 : 1, pool.is_series? ? 0 : 1, pool.name] } %>
<% pools.each do |pool| %> <% pools.each do |pool| %>
<%= render "posts/partials/show/pool_list_item", pool: pool, post: post, selected: is_pool_selected?(pool) %> <%= render "posts/partials/show/pool_list_item", pool: pool, post: post, selected: is_pool_selected?(pool) %>
<% end %> <% end %>

View File

@@ -1,4 +1,4 @@
<%= content_tag :li, id: "nav-link-for-pool-#{pool.id}", class: "pool-category-#{pool.category} pool-selected-#{selected}" do -%> <%= tag.li id: "nav-link-for-pool-#{pool.id}", class: "pool-category-#{pool.category}", "data-selected": selected do -%>
<% if !pool.first_post?(post.id) && pool.post_ids.first -%> <% if !pool.first_post?(post.id) && pool.post_ids.first -%>
<%= link_to("&laquo;".html_safe, post_path(pool.post_ids.first, pool_id: pool.id), class: "first", title: "to page 1") %> <%= link_to("&laquo;".html_safe, post_path(pool.post_ids.first, pool_id: pool.id), class: "first", title: "to page 1") %>
<% else -%> <% else -%>

View File

@@ -0,0 +1,23 @@
class ChangePostIdsToArrayOnFavoriteGroups < ActiveRecord::Migration[6.0]
def up
execute "set statement_timeout = 0"
change_column_default :favorite_groups, :post_ids, nil
change_column :favorite_groups, :post_ids, "integer[]", using: "string_to_array(post_ids, ' ')::integer[]"
change_column_default :favorite_groups, :post_ids, "{}"
add_index :favorite_groups, :post_ids, using: :gin
remove_column :favorite_groups, :post_count
end
def down
execute "set statement_timeout = 0"
remove_index :favorite_groups, :post_ids
change_column_default :favorite_groups, :post_ids, nil
change_column :favorite_groups, :post_ids, :text, using: "array_to_string(post_ids, ' ')"
change_column_default :favorite_groups, :post_ids, ""
add_column :favorite_groups, :post_count, :integer, default: 0, null: false
end
end

View File

@@ -921,8 +921,7 @@ CREATE TABLE public.favorite_groups (
id integer NOT NULL, id integer NOT NULL,
name text NOT NULL, name text NOT NULL,
creator_id integer NOT NULL, creator_id integer NOT NULL,
post_ids text DEFAULT ''::text NOT NULL, post_ids integer[] DEFAULT '{}'::integer[] NOT NULL,
post_count integer DEFAULT 0 NOT NULL,
created_at timestamp without time zone NOT NULL, created_at timestamp without time zone NOT NULL,
updated_at timestamp without time zone NOT NULL, updated_at timestamp without time zone NOT NULL,
is_public boolean DEFAULT false NOT NULL is_public boolean DEFAULT false NOT NULL
@@ -4975,6 +4974,13 @@ CREATE INDEX index_favorite_groups_on_creator_id ON public.favorite_groups USING
CREATE INDEX index_favorite_groups_on_lower_name ON public.favorite_groups USING btree (lower(name)); CREATE INDEX index_favorite_groups_on_lower_name ON public.favorite_groups USING btree (lower(name));
--
-- Name: index_favorite_groups_on_post_ids; Type: INDEX; Schema: public; Owner: -
--
CREATE INDEX index_favorite_groups_on_post_ids ON public.favorite_groups USING gin (post_ids);
-- --
-- Name: index_favorites_0_on_post_id; Type: INDEX; Schema: public; Owner: - -- Name: index_favorites_0_on_post_id; Type: INDEX; Schema: public; Owner: -
-- --
@@ -7400,6 +7406,7 @@ INSERT INTO "schema_migrations" (version) VALUES
('20191117200404'), ('20191117200404'),
('20191119061018'), ('20191119061018'),
('20191223032633'), ('20191223032633'),
('20200114204550'); ('20200114204550'),
('20200115010442');

View File

@@ -33,7 +33,7 @@ class FavoriteGroupsControllerTest < ActionDispatch::IntegrationTest
context "create action" do context "create action" do
should "render" do should "render" do
post_auth favorite_groups_path, @user, params: { favorite_group: FactoryBot.attributes_for(:favorite_group) } post_auth favorite_groups_path, @user, params: { favorite_group: FactoryBot.attributes_for(:favorite_group) }
assert_redirected_to favorite_groups_path assert_redirected_to favorite_group_path(FavoriteGroup.last)
end end
end end
@@ -47,11 +47,11 @@ class FavoriteGroupsControllerTest < ActionDispatch::IntegrationTest
context "update action" do context "update action" do
should "update posts" do should "update posts" do
@posts = create_list(:post, 2) @posts = create_list(:post, 2)
put_auth favorite_group_path(@favgroup), @user, params: { favorite_group: { name: "foo", post_id_array: @posts.map(&:id) } } put_auth favorite_group_path(@favgroup), @user, params: { favorite_group: { name: "foo", post_ids: @posts.map(&:id).join(" ") } }
assert_redirected_to @favgroup assert_redirected_to @favgroup
assert_equal("foo", @favgroup.reload.name) assert_equal("foo", @favgroup.reload.name)
assert_equal(@posts.map(&:id), @favgroup.post_id_array) assert_equal(@posts.map(&:id), @favgroup.post_ids)
end end
end end
@@ -71,7 +71,7 @@ class FavoriteGroupsControllerTest < ActionDispatch::IntegrationTest
put_auth add_post_favorite_group_path(@favgroup), @user, params: {post_id: @post.id, format: "js"} put_auth add_post_favorite_group_path(@favgroup), @user, params: {post_id: @post.id, format: "js"}
assert_response :success assert_response :success
@favgroup.reload @favgroup.reload
assert_equal([@post.id], @favgroup.post_id_array) assert_equal([@post.id], @favgroup.post_ids)
end end
end end
end end

View File

@@ -68,10 +68,10 @@ class FavoriteTest < ActiveSupport::TestCase
end end
should "remove it from all favorite groups" do should "remove it from all favorite groups" do
assert_equal(@post.id.to_s, @fav_group.post_ids) assert_equal([@post.id], @fav_group.post_ids)
@post.expunge! @post.expunge!
@fav_group.reload @fav_group.reload
assert_equal("", @fav_group.post_ids) assert_equal([], @fav_group.post_ids)
end end
end end
end end