Comments have three states: visible, hidden, and invisible. Visible
comments are always shown. Hidden comments are not shown until the user
clicks 'Show all comments'. Invisible comments are never shown to the
user. Deleted comments are treated as hidden for moderators and
invisible for normal users. Thresholded comments are treated as hidden
for all users.
Rewrite the implementation of related tags to be simpler, faster, and
more accurate:
* The related tags are now calculated by taking a random sample of 1000
posts, finding the top 250 most frequent tags among those posts, then
ordering those tags by cosine similarity.
* Related tags can generally be calculated in 50-300ms at these sample
sizes. Very high sample sizes (25000+ posts) are still relatively fast
(1-3 seconds), but generally they don't improve accuracy much.
* Related tags are now cached in redis rather than in the tags table.
The related_tags column in the tags table is no longer used.
* Only the related tags in the search taglist are cached. The related
tags returned by the 'Related tags' button are not cached.
* The cache lifetime is a fixed 4 hours.
* The 'Related tags' button now works with metatags.
* The /related_tag page now works with metatags and multitag searches.
Fixes#4134, #4146.
* Drop support for `source:pixiv/artist-name` searches. This was a hack
that only worked on old pixiv urls that haven't been used for years.
* Replace the old SourcePattern(lower(source)) index with a trigram index.
Previously if a pool had >100 posts then the 'Order' link wouldn't
appear in the navbar, but it was still possible to visit the pool order
page directly. If a user did so, only the first 100 posts in the pool
would be shown in the drag-and-drop widget. If they tried to reorder the
pool anyway, then everything beyond the first 100 posts would be
silently removed from the pool.
Now we always show the 'Order' link, but we disable the drag-and-drop
reordering widget when the pool has >100 posts to prevent posts from
being silently removed.
Fixes a conflict with `Enumerable#excluding` in Rails 6.
Rename Array#without and Enumerable#without to Array#excluding and
Enumerable#excluding. Old method names are retained as aliases.
Bug: sending dmails failed for members.
Cause: using lambdas with `rakismet_attrs` failed because unexpected
arguments are passed to the lambdas. Using procs works because the
arguments are ignored.
Also fix the tests to actually test akismet. We didn't catch this
because the tests mocked out the `spam?` call.
Certain parts of comment rendering triggered sql queries that we didn't
really need to do. Rework things to avoid this.
* Preload comment creators in order to display commenter names with link_to_user.
* Preload comment votes in order to display "undo vote" links. Only preload
votes for members since anonymous users can't vote and don't have "undo
vote" links.
* Rework various conditionals to do the filtering in Ruby so that we
avoid issuing any extra queries in sql.
* Avoid issuing any queries at all when the post doesn't have any
comments (when last_commented_at is blank).
Changes to the /wiki_page_versions global listing:
* Add "diff" links that show you what changed in the given edit.
* Add "?" links that take you to the current version of the wiki.
* Add "»" links next to wiki page titles that take you to the wiki's full edit history.
* Add "»" links next to usernames that take you to the user's full edit history.
* Add a "Status" column that shows whether the wiki page was created,
deleted, undeleted, or renamed.
* Link to /wiki_page_versions in sidebar, not /wiki_pages?order=time.
Changes:
* Drop Users.id_to_name.
* Don't cache Users.name_to_id.
* Replace calls to name_to_id with find_by_name when possible.
* Don't autodefine creator_name in belongs_to_creator.
* Don't autodefine updater_name in belongs_to_updater.
* Instead manually define creator_name / updater_name only on models that need
to return these fields in the api.
id_to_name was cached to reduce the impact of N+1 query patterns in
certain places, especially in api responses that return creator_name /
updater_name fields. But it still meant we were doing N calls to
memcache. Using `includes` to prefetch users avoids this N+1 pattern.
name_to_id had no need be cached, it was never used in any performance-
sensitive contexts.
Avoiding caching also avoids the need to keep these caches consistent.
Fix find_by_name and name_to_id to use normalize_name properly, so that
they ignore leading/trailing whitespace. This fixes various search forms
failing to return results when the username field contains trailing
whitespace (inserted by autocomplete).
* Fix tests to run the searches for real instead of mocking everything out.
* Fix SavedSearch.populate to only use the read only database in
production because in breaks things in tests. Specifically:
the posts get created in one db connection but searched for in
another, but the second transaction doesn't see the uncommitted posts
in the first transaction, so the search doesn't work.
* Drop /posts?ro=true param (broken).
* Clean up tag_match (rescuing PG::ConnectionBad didn't do anything, we
just build the query here, we don't run it).
* Don't allow adding tags with invalid names when they already exist in
the tags table.
* If an invalid tag is added, show an warning and ignore the tag instead
of failing with a hard error.
* Move the _(cosplay) tag validation into the tag name validator.
Favoriting posts sometimes fails with ActiveRecord::LockWaitTimeout
errors. This happens when a user tries to favorite multiple posts in
short succession. In that case we want the lock to block and wait for
the other favorite to go through, not to immediately fail.
Bug: Searching for an aliased tag returns an empty page instead of
showing the results for the real tag.
Cause: The query parsing code runs the search string through
`.mb_chars.downcase` before calling `TagAlias.to_aliased`, so the input
to `to_aliased` is actually a ActiveSupport::Multibyte::Chars object.
This breaks the `aliases[name]` hash lookup because `name` is not a
plain string.
Fixup for c7bcce429.
During single-tag searches we look up the tag once in Post.fast_count
and later on when rendering the wiki excerpt. Doing a raw query here
meant that Rails couldn't cache the query, so it got ran again when
rendering the excerpt.
Post.fast_count calls Tag.normalize_query to normalize the tag string
used for the pfc cache key. This slightly improves cache sharing at the
expense of an extra query during tag searches. The extra query isn't
worth it.