counter cache for user model
This commit is contained in:
2
TODO.md
2
TODO.md
@@ -38,4 +38,4 @@
|
||||
- [ ] fix for IDs that have a dot in them - e.g. https://refurrer.com/users/fa@jakke.
|
||||
- [ ] Rich inline links to e621 e.g. https://refurrer.com/posts/fa@60070060
|
||||
- [ ] Find FaPost that have favs recorded but no scan / file, enqueue scan
|
||||
- [ ] Bunch of posts with empty responses: posts = Domain::Post.joins(files: :log_entry).where(files: { http_log_entries: { response_sha256: BlobFile::EMPTY_FILE_SHA256 }}).limit(10)
|
||||
- [x] Bunch of posts with empty responses: posts = Domain::Post.joins(files: :log_entry).where(files: { http_log_entries: { response_sha256: BlobFile::EMPTY_FILE_SHA256 }}).limit(10)
|
||||
|
||||
@@ -128,6 +128,10 @@ class Domain::E621::Job::ScanUserFavsJob < Domain::E621::Job::Base
|
||||
end
|
||||
end
|
||||
|
||||
# Use reset_counters to update the counter cache after using upsert_all
|
||||
Domain::User.reset_counters(user.id, :user_post_favs)
|
||||
logger.info("[reset user_post_favs counter cache for user: #{user.id}]")
|
||||
|
||||
logger.info(
|
||||
[
|
||||
"[favs scanned: #{post_ids.size.to_s.bold}]",
|
||||
|
||||
@@ -565,7 +565,8 @@ class Domain::Fa::Job::Base < Scraper::JobBase
|
||||
).returns(T::Boolean)
|
||||
end
|
||||
def user_disabled_or_not_found?(user, response)
|
||||
if response.status_code != 200
|
||||
# HTTP 400 is returned when the user is not found
|
||||
if response.status_code != 200 && response.status_code != 400
|
||||
fatal_error(
|
||||
"http #{response.status_code}, log entry #{response.log_entry.id}",
|
||||
)
|
||||
|
||||
@@ -98,6 +98,14 @@ class Domain::Fa::Job::FavsJob < Domain::Fa::Job::Base
|
||||
unique_by: %i[user_id post_id],
|
||||
)
|
||||
end
|
||||
|
||||
# Use reset_counters to update the counter cache after using upsert_all
|
||||
Domain::User.reset_counters(user.id, :user_post_favs)
|
||||
logger.info(
|
||||
format_tags(
|
||||
make_tag("reset user_post_favs counter cache for user", user.id),
|
||||
),
|
||||
)
|
||||
end
|
||||
|
||||
user.scanned_favs_at = Time.zone.now
|
||||
|
||||
@@ -77,6 +77,14 @@ module Domain::Fa::Job
|
||||
{ user_id: user.id, post_id: post_id }
|
||||
end,
|
||||
)
|
||||
|
||||
# Use reset_counters to update the counter cache after using insert_all
|
||||
Domain::User.reset_counters(user.id, :user_post_favs)
|
||||
logger.info(
|
||||
format_tags(
|
||||
make_tag("reset user_post_favs counter cache for user", user.id),
|
||||
),
|
||||
)
|
||||
end
|
||||
|
||||
if missing_fav_post_ids.include? recent_fav_post_ids.last
|
||||
@@ -125,6 +133,25 @@ module Domain::Fa::Job
|
||||
{ from_id: watcher_id, to_id: user.id }
|
||||
end,
|
||||
)
|
||||
|
||||
# Use reset_counters to update follows_to for the current user
|
||||
Domain::User.reset_counters(user.id, :user_user_follows_to)
|
||||
logger.info(
|
||||
format_tags(
|
||||
make_tag(
|
||||
"reset user_user_follows_to counter cache for user",
|
||||
user.id,
|
||||
),
|
||||
),
|
||||
)
|
||||
|
||||
# Update follows_from counts for watcher users
|
||||
missing_watcher_ids.each_slice(100) do |batch_ids|
|
||||
batch_ids.each do |watcher_id|
|
||||
Domain::User.reset_counters(watcher_id, :user_user_follows_from)
|
||||
end
|
||||
end
|
||||
|
||||
logger.info("added #{num_missing.to_s.bold} new watchers")
|
||||
end
|
||||
|
||||
@@ -140,22 +167,45 @@ module Domain::Fa::Job
|
||||
find_or_create_users_by_recent_users(recent_watched)
|
||||
raise("invariant") unless recent_watched_users.size == recent_watched.size
|
||||
recent_watched_user_ids = recent_watched_users.map { |m| T.must(m.id) }
|
||||
known_watched_users =
|
||||
user.followed_users.where(id: recent_watched_user_ids).to_a
|
||||
missing_watched_users = recent_watched_users - known_watched_users
|
||||
known_watched_user_ids =
|
||||
user.followed_users.where(id: recent_watched_user_ids).pluck(:id)
|
||||
missing_watched_users =
|
||||
recent_watched_users.reject do |u|
|
||||
known_watched_user_ids.include?(u.id)
|
||||
end
|
||||
missing_watched_user_ids = missing_watched_users.map { |m| T.must(m.id) }
|
||||
|
||||
if missing_watched_users.empty?
|
||||
if missing_watched_user_ids.empty?
|
||||
logger.info("no new users watched")
|
||||
user.scanned_follows_at = Time.current
|
||||
return
|
||||
end
|
||||
|
||||
num_missing = missing_watched_users.size
|
||||
num_missing = missing_watched_user_ids.size
|
||||
Domain::UserUserFollow.insert_all!(
|
||||
missing_watched_users.map do |watched_user|
|
||||
{ from_id: user.id, to_id: watched_user.id }
|
||||
missing_watched_user_ids.map do |watched_user_id|
|
||||
{ from_id: user.id, to_id: watched_user_id }
|
||||
end,
|
||||
)
|
||||
|
||||
# Use reset_counters to update follows_from for the current user
|
||||
Domain::User.reset_counters(user.id, :user_user_follows_from)
|
||||
logger.info(
|
||||
format_tags(
|
||||
make_tag(
|
||||
"reset user_user_follows_from counter cache for user",
|
||||
user.id,
|
||||
),
|
||||
),
|
||||
)
|
||||
|
||||
# Update follows_to counts for users who were followed
|
||||
missing_watched_user_ids.each_slice(100) do |batch_ids|
|
||||
batch_ids.each do |watched_user_id|
|
||||
Domain::User.reset_counters(watched_user_id, :user_user_follows_to)
|
||||
end
|
||||
end
|
||||
|
||||
logger.info("added #{num_missing.to_s.bold} new users watched")
|
||||
|
||||
last_watched_user = recent_watched_users.last
|
||||
|
||||
@@ -154,6 +154,15 @@ class Domain::Fa::Job::UserPageJob < Domain::Fa::Job::Base
|
||||
faved_posts.map(&:id).compact.map { |post_id| { post_id: } },
|
||||
unique_by: %i[user_id post_id],
|
||||
)
|
||||
|
||||
# Use reset_counters to update the counter cache after upserting favs
|
||||
Domain::User.reset_counters(user.id, :user_post_favs)
|
||||
logger.info(
|
||||
format_tags(
|
||||
make_tag("reset user_post_favs counter cache for user", user.id),
|
||||
),
|
||||
)
|
||||
|
||||
user.scanned_favs_at = Time.current
|
||||
end
|
||||
end
|
||||
@@ -182,10 +191,31 @@ class Domain::Fa::Job::UserPageJob < Domain::Fa::Job::Base
|
||||
) { |user| user.name = recent_user.name }
|
||||
end
|
||||
|
||||
watched_user_ids = watched_users.map(&:id).compact
|
||||
|
||||
user.user_user_follows_from.upsert_all(
|
||||
watched_users.map(&:id).compact.map { |user_id| { to_id: user_id } },
|
||||
watched_user_ids.map { |user_id| { to_id: user_id } },
|
||||
unique_by: %i[from_id to_id],
|
||||
)
|
||||
|
||||
# Use reset_counters to update follows_from for the current user
|
||||
Domain::User.reset_counters(user.id, :user_user_follows_from)
|
||||
logger.info(
|
||||
format_tags(
|
||||
make_tag(
|
||||
"reset user_user_follows_from counter cache for user",
|
||||
user.id,
|
||||
),
|
||||
),
|
||||
)
|
||||
|
||||
# Update follows_to counts for users who were followed
|
||||
watched_user_ids.each_slice(100) do |batch_ids|
|
||||
batch_ids.each do |watched_user_id|
|
||||
Domain::User.reset_counters(watched_user_id, :user_user_follows_to)
|
||||
end
|
||||
end
|
||||
|
||||
user.scanned_follows_at = Time.current
|
||||
elsif recent_watching.any?
|
||||
# if there are watchers, find the ones we've already recorded. if
|
||||
@@ -239,13 +269,31 @@ class Domain::Fa::Job::UserPageJob < Domain::Fa::Job::Base
|
||||
) { |user| user.name = recent_user.name }
|
||||
end
|
||||
|
||||
watcher_ids = watched_by_users.map(&:id).compact
|
||||
|
||||
user.user_user_follows_to.upsert_all(
|
||||
watched_by_users
|
||||
.map(&:id)
|
||||
.compact
|
||||
.map { |user_id| { from_id: user_id } },
|
||||
watcher_ids.map { |user_id| { from_id: user_id } },
|
||||
unique_by: %i[from_id to_id],
|
||||
)
|
||||
|
||||
# Use reset_counters to update follows_to for the current user
|
||||
Domain::User.reset_counters(user.id, :user_user_follows_to)
|
||||
logger.info(
|
||||
format_tags(
|
||||
make_tag(
|
||||
"reset user_user_follows_to counter cache for user",
|
||||
user.id,
|
||||
),
|
||||
),
|
||||
)
|
||||
|
||||
# Update follows_from counts for watchers
|
||||
watcher_ids.each_slice(100) do |batch_ids|
|
||||
batch_ids.each do |watcher_id|
|
||||
Domain::User.reset_counters(watcher_id, :user_user_follows_from)
|
||||
end
|
||||
end
|
||||
|
||||
user.scanned_followed_by_at = Time.current
|
||||
return
|
||||
end
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
# typed: strict
|
||||
class Domain::PostFileThumbnailJob < Scraper::JobBase
|
||||
queue_as :thumbnails
|
||||
discard_on Vips::Error
|
||||
|
||||
sig { override.returns(Symbol) }
|
||||
def self.http_factory_method
|
||||
|
||||
@@ -931,6 +931,12 @@ class Domain::MigrateToDomain
|
||||
ON CONFLICT (user_id, post_id) DO NOTHING
|
||||
SQL
|
||||
|
||||
# Use reset_counters to update the counter cache after inserting favs
|
||||
Domain::User.reset_counters(user.id, :user_post_favs)
|
||||
logger.info(
|
||||
"Reset user_post_favs counter cache for user #{user.name} (ID: #{user.id})",
|
||||
)
|
||||
|
||||
if user.faved_posts.count != old_user.fav_posts.count
|
||||
logger.error(
|
||||
"favs mismatch for #{user.name}: (#{user.faved_posts.count} != #{old_user.fav_posts.count})",
|
||||
@@ -962,6 +968,22 @@ class Domain::MigrateToDomain
|
||||
)
|
||||
end
|
||||
|
||||
# Use reset_counters to update follows_from for the current user
|
||||
Domain::User.reset_counters(user.id, :user_user_follows_from)
|
||||
logger.info(
|
||||
"Reset user_user_follows_from counter cache for user #{user.name} (ID: #{user.id})",
|
||||
)
|
||||
|
||||
# Update follows_to counts for users who were followed
|
||||
new_user_ids.each_slice(1000) do |batch_ids|
|
||||
batch_ids.each do |user_id|
|
||||
Domain::User.reset_counters(user_id, :user_user_follows_to)
|
||||
end
|
||||
end
|
||||
logger.info(
|
||||
"Reset user_user_follows_to counter cache for #{new_user_ids.size} followed users",
|
||||
)
|
||||
|
||||
if new_user_ids.size != old_user.follows.count
|
||||
logger.error(
|
||||
"followers mismatch for #{user.name}: (#{user.followed_users.count} != #{old_user.follows.count})",
|
||||
@@ -987,6 +1009,12 @@ class Domain::MigrateToDomain
|
||||
)
|
||||
end
|
||||
|
||||
# Use reset_counters to update the counter cache after upserting favs
|
||||
Domain::User.reset_counters(new_user.id, :user_post_favs)
|
||||
logger.info(
|
||||
"Reset user_post_favs counter cache for user #{new_user.name} (ID: #{new_user.id})",
|
||||
)
|
||||
|
||||
if new_user.faved_posts.count != old_user.faved_posts.count
|
||||
logger.error(
|
||||
"favs mismatch for #{new_user.name}: (#{new_user.faved_posts.count} != #{old_user.faved_posts.count})",
|
||||
|
||||
@@ -17,6 +17,27 @@ class Domain::User < ReduxApplicationRecord
|
||||
:class_has_followed_by_users,
|
||||
:due_at_timestamp_fields
|
||||
|
||||
# Counter cache methods with fallbacks
|
||||
sig { returns(Integer) }
|
||||
def user_post_creations_count
|
||||
super || user_post_creations.count
|
||||
end
|
||||
|
||||
sig { returns(Integer) }
|
||||
def user_post_favs_count
|
||||
super || user_post_favs.count
|
||||
end
|
||||
|
||||
sig { returns(Integer) }
|
||||
def user_user_follows_from_count
|
||||
super || user_user_follows_from.count
|
||||
end
|
||||
|
||||
sig { returns(Integer) }
|
||||
def user_user_follows_to_count
|
||||
super || user_user_follows_to.count
|
||||
end
|
||||
|
||||
sig(:final) { returns(T::Boolean) }
|
||||
def has_created_posts?
|
||||
class_has_created_posts.present?
|
||||
|
||||
@@ -10,5 +10,6 @@ class Domain::UserPostCreation < ReduxApplicationRecord
|
||||
inverse_of: :user_post_creations
|
||||
belongs_to :user,
|
||||
class_name: "::Domain::User",
|
||||
inverse_of: :user_post_creations
|
||||
inverse_of: :user_post_creations,
|
||||
counter_cache: true
|
||||
end
|
||||
|
||||
@@ -3,7 +3,10 @@ class Domain::UserPostFav < ReduxApplicationRecord
|
||||
self.table_name = "domain_user_post_favs"
|
||||
self.primary_key = %i[user_id post_id]
|
||||
|
||||
belongs_to :user, class_name: "Domain::User", inverse_of: :user_post_favs
|
||||
belongs_to :user,
|
||||
class_name: "Domain::User",
|
||||
inverse_of: :user_post_favs,
|
||||
counter_cache: true
|
||||
belongs_to :post, class_name: "Domain::Post", inverse_of: :user_post_favs
|
||||
|
||||
scope :for_post_type,
|
||||
|
||||
@@ -2,6 +2,10 @@ class Domain::UserUserFollow < ReduxApplicationRecord
|
||||
self.table_name = "domain_user_user_follows"
|
||||
self.primary_key = %i[from_id to_id]
|
||||
|
||||
belongs_to :from, class_name: "Domain::User"
|
||||
belongs_to :to, class_name: "Domain::User"
|
||||
belongs_to :from,
|
||||
class_name: "Domain::User",
|
||||
counter_cache: :user_user_follows_from_count
|
||||
belongs_to :to,
|
||||
class_name: "Domain::User",
|
||||
counter_cache: :user_user_follows_to_count
|
||||
end
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
class AddUserCountersToDomainUsers < ActiveRecord::Migration[7.2]
|
||||
def up
|
||||
add_column :domain_users,
|
||||
:user_post_creations_count,
|
||||
:integer,
|
||||
default: nil,
|
||||
null: true
|
||||
add_column :domain_users,
|
||||
:user_post_favs_count,
|
||||
:integer,
|
||||
default: nil,
|
||||
null: true
|
||||
add_column :domain_users,
|
||||
:user_user_follows_from_count,
|
||||
:integer,
|
||||
default: nil,
|
||||
null: true
|
||||
add_column :domain_users,
|
||||
:user_user_follows_to_count,
|
||||
:integer,
|
||||
default: nil,
|
||||
null: true
|
||||
end
|
||||
|
||||
def down
|
||||
remove_column :domain_users, :user_post_creations_count
|
||||
remove_column :domain_users, :user_post_favs_count
|
||||
remove_column :domain_users, :user_user_follows_from_count
|
||||
remove_column :domain_users, :user_user_follows_to_count
|
||||
end
|
||||
end
|
||||
@@ -3160,7 +3160,11 @@ CREATE TABLE public.domain_users (
|
||||
type public.domain_user_type NOT NULL,
|
||||
json_attributes jsonb DEFAULT '{}'::jsonb,
|
||||
created_at timestamp(6) without time zone NOT NULL,
|
||||
updated_at timestamp(6) without time zone NOT NULL
|
||||
updated_at timestamp(6) without time zone NOT NULL,
|
||||
user_post_creations_count integer,
|
||||
user_post_favs_count integer,
|
||||
user_user_follows_from_count integer,
|
||||
user_user_follows_to_count integer
|
||||
);
|
||||
|
||||
|
||||
@@ -8910,6 +8914,7 @@ ALTER TABLE ONLY public.domain_twitter_tweets
|
||||
SET search_path TO "$user", public;
|
||||
|
||||
INSERT INTO "schema_migrations" (version) VALUES
|
||||
('20250321050628'),
|
||||
('20250310001341'),
|
||||
('20250310001005'),
|
||||
('20250306021628'),
|
||||
|
||||
79
lib/tasks/counters.rake
Normal file
79
lib/tasks/counters.rake
Normal file
@@ -0,0 +1,79 @@
|
||||
namespace :counters do
|
||||
# Generic counter reset helper that works with any model
|
||||
def reset_model_counters(model_class, counter_names, batch_size: 1000)
|
||||
counter_names = Array(counter_names)
|
||||
model_name = model_class.name.demodulize.underscore
|
||||
counter_desc =
|
||||
counter_names
|
||||
.map { |n| n.to_s.sub("#{model_name}_", "").sub("user_", "") }
|
||||
.join(" and ")
|
||||
|
||||
total = model_class.count
|
||||
puts "Resetting #{counter_desc} counter cache for #{total} #{model_name.pluralize}..."
|
||||
|
||||
pb = ProgressBar.create(total: total, format: "%t: %c/%C %B %p%% %a %e")
|
||||
|
||||
model_class
|
||||
.pluck(:id)
|
||||
.each_slice(batch_size) do |ids|
|
||||
model_class.transaction do
|
||||
ids.each do |id|
|
||||
model_class.reset_counters(id, *counter_names)
|
||||
pb.increment
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
puts "Done!"
|
||||
end
|
||||
|
||||
namespace :domain do
|
||||
namespace :user do
|
||||
def reset_user_counters(counter_names)
|
||||
reset_model_counters(Domain::User, counter_names)
|
||||
end
|
||||
|
||||
desc "Reset all user counter caches"
|
||||
task all: :environment do
|
||||
reset_user_counters(
|
||||
%i[
|
||||
user_post_creations
|
||||
user_post_favs
|
||||
user_user_follows_from
|
||||
user_user_follows_to
|
||||
],
|
||||
)
|
||||
end
|
||||
|
||||
desc "Reset post-related counter caches only (creations and favs)"
|
||||
task posts: :environment do
|
||||
reset_user_counters(%i[user_post_creations user_post_favs])
|
||||
end
|
||||
|
||||
desc "Reset follow-related counter caches only (follows_from and follows_to)"
|
||||
task follows: :environment do
|
||||
reset_user_counters(%i[user_user_follows_from user_user_follows_to])
|
||||
end
|
||||
|
||||
desc "Reset user_post_creations_count counter cache"
|
||||
task user_post_creations_count: :environment do
|
||||
reset_user_counters(:user_post_creations)
|
||||
end
|
||||
|
||||
desc "Reset user_post_favs_count counter cache"
|
||||
task user_post_favs_count: :environment do
|
||||
reset_user_counters(:user_post_favs)
|
||||
end
|
||||
|
||||
desc "Reset user_user_follows_from_count counter cache"
|
||||
task user_user_follows_from_count: :environment do
|
||||
reset_user_counters(:user_user_follows_from)
|
||||
end
|
||||
|
||||
desc "Reset user_user_follows_to_count counter cache"
|
||||
task user_user_follows_to_count: :environment do
|
||||
reset_user_counters(:user_user_follows_to)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -70,6 +70,9 @@ namespace :blob_file do
|
||||
puts "error saving blob file #{sha256_hex}: #{e}"
|
||||
end
|
||||
end
|
||||
rescue => e
|
||||
puts "error migrating blob entry: #{missing_sha256s.map { |sha256| HexUtil.bin2hex(sha256) }}"
|
||||
raise e
|
||||
end
|
||||
num_migrated
|
||||
end
|
||||
|
||||
228
sorbet/rbi/dsl/domain/user.rbi
generated
228
sorbet/rbi/dsl/domain/user.rbi
generated
@@ -1006,6 +1006,18 @@ class Domain::User
|
||||
sig { void }
|
||||
def restore_updated_at!; end
|
||||
|
||||
sig { void }
|
||||
def restore_user_post_creations_count!; end
|
||||
|
||||
sig { void }
|
||||
def restore_user_post_favs_count!; end
|
||||
|
||||
sig { void }
|
||||
def restore_user_user_follows_from_count!; end
|
||||
|
||||
sig { void }
|
||||
def restore_user_user_follows_to_count!; end
|
||||
|
||||
sig { returns(T.nilable([T.nilable(::ActiveSupport::TimeWithZone), T.nilable(::ActiveSupport::TimeWithZone)])) }
|
||||
def saved_change_to_created_at; end
|
||||
|
||||
@@ -1048,6 +1060,30 @@ class Domain::User
|
||||
sig { returns(T::Boolean) }
|
||||
def saved_change_to_updated_at?; end
|
||||
|
||||
sig { returns(T.nilable([T.nilable(::Integer), T.nilable(::Integer)])) }
|
||||
def saved_change_to_user_post_creations_count; end
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def saved_change_to_user_post_creations_count?; end
|
||||
|
||||
sig { returns(T.nilable([T.nilable(::Integer), T.nilable(::Integer)])) }
|
||||
def saved_change_to_user_post_favs_count; end
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def saved_change_to_user_post_favs_count?; end
|
||||
|
||||
sig { returns(T.nilable([T.nilable(::Integer), T.nilable(::Integer)])) }
|
||||
def saved_change_to_user_user_follows_from_count; end
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def saved_change_to_user_user_follows_from_count?; end
|
||||
|
||||
sig { returns(T.nilable([T.nilable(::Integer), T.nilable(::Integer)])) }
|
||||
def saved_change_to_user_user_follows_to_count; end
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def saved_change_to_user_user_follows_to_count?; end
|
||||
|
||||
sig { returns(T.untyped) }
|
||||
def type; end
|
||||
|
||||
@@ -1148,6 +1184,186 @@ class Domain::User
|
||||
sig { void }
|
||||
def updated_at_will_change!; end
|
||||
|
||||
sig { returns(T.nilable(::Integer)) }
|
||||
def user_post_creations_count; end
|
||||
|
||||
sig { params(value: T.nilable(::Integer)).returns(T.nilable(::Integer)) }
|
||||
def user_post_creations_count=(value); end
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def user_post_creations_count?; end
|
||||
|
||||
sig { returns(T.nilable(::Integer)) }
|
||||
def user_post_creations_count_before_last_save; end
|
||||
|
||||
sig { returns(T.untyped) }
|
||||
def user_post_creations_count_before_type_cast; end
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def user_post_creations_count_came_from_user?; end
|
||||
|
||||
sig { returns(T.nilable([T.nilable(::Integer), T.nilable(::Integer)])) }
|
||||
def user_post_creations_count_change; end
|
||||
|
||||
sig { returns(T.nilable([T.nilable(::Integer), T.nilable(::Integer)])) }
|
||||
def user_post_creations_count_change_to_be_saved; end
|
||||
|
||||
sig { params(from: T.nilable(::Integer), to: T.nilable(::Integer)).returns(T::Boolean) }
|
||||
def user_post_creations_count_changed?(from: T.unsafe(nil), to: T.unsafe(nil)); end
|
||||
|
||||
sig { returns(T.nilable(::Integer)) }
|
||||
def user_post_creations_count_in_database; end
|
||||
|
||||
sig { returns(T.nilable([T.nilable(::Integer), T.nilable(::Integer)])) }
|
||||
def user_post_creations_count_previous_change; end
|
||||
|
||||
sig { params(from: T.nilable(::Integer), to: T.nilable(::Integer)).returns(T::Boolean) }
|
||||
def user_post_creations_count_previously_changed?(from: T.unsafe(nil), to: T.unsafe(nil)); end
|
||||
|
||||
sig { returns(T.nilable(::Integer)) }
|
||||
def user_post_creations_count_previously_was; end
|
||||
|
||||
sig { returns(T.nilable(::Integer)) }
|
||||
def user_post_creations_count_was; end
|
||||
|
||||
sig { void }
|
||||
def user_post_creations_count_will_change!; end
|
||||
|
||||
sig { returns(T.nilable(::Integer)) }
|
||||
def user_post_favs_count; end
|
||||
|
||||
sig { params(value: T.nilable(::Integer)).returns(T.nilable(::Integer)) }
|
||||
def user_post_favs_count=(value); end
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def user_post_favs_count?; end
|
||||
|
||||
sig { returns(T.nilable(::Integer)) }
|
||||
def user_post_favs_count_before_last_save; end
|
||||
|
||||
sig { returns(T.untyped) }
|
||||
def user_post_favs_count_before_type_cast; end
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def user_post_favs_count_came_from_user?; end
|
||||
|
||||
sig { returns(T.nilable([T.nilable(::Integer), T.nilable(::Integer)])) }
|
||||
def user_post_favs_count_change; end
|
||||
|
||||
sig { returns(T.nilable([T.nilable(::Integer), T.nilable(::Integer)])) }
|
||||
def user_post_favs_count_change_to_be_saved; end
|
||||
|
||||
sig { params(from: T.nilable(::Integer), to: T.nilable(::Integer)).returns(T::Boolean) }
|
||||
def user_post_favs_count_changed?(from: T.unsafe(nil), to: T.unsafe(nil)); end
|
||||
|
||||
sig { returns(T.nilable(::Integer)) }
|
||||
def user_post_favs_count_in_database; end
|
||||
|
||||
sig { returns(T.nilable([T.nilable(::Integer), T.nilable(::Integer)])) }
|
||||
def user_post_favs_count_previous_change; end
|
||||
|
||||
sig { params(from: T.nilable(::Integer), to: T.nilable(::Integer)).returns(T::Boolean) }
|
||||
def user_post_favs_count_previously_changed?(from: T.unsafe(nil), to: T.unsafe(nil)); end
|
||||
|
||||
sig { returns(T.nilable(::Integer)) }
|
||||
def user_post_favs_count_previously_was; end
|
||||
|
||||
sig { returns(T.nilable(::Integer)) }
|
||||
def user_post_favs_count_was; end
|
||||
|
||||
sig { void }
|
||||
def user_post_favs_count_will_change!; end
|
||||
|
||||
sig { returns(T.nilable(::Integer)) }
|
||||
def user_user_follows_from_count; end
|
||||
|
||||
sig { params(value: T.nilable(::Integer)).returns(T.nilable(::Integer)) }
|
||||
def user_user_follows_from_count=(value); end
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def user_user_follows_from_count?; end
|
||||
|
||||
sig { returns(T.nilable(::Integer)) }
|
||||
def user_user_follows_from_count_before_last_save; end
|
||||
|
||||
sig { returns(T.untyped) }
|
||||
def user_user_follows_from_count_before_type_cast; end
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def user_user_follows_from_count_came_from_user?; end
|
||||
|
||||
sig { returns(T.nilable([T.nilable(::Integer), T.nilable(::Integer)])) }
|
||||
def user_user_follows_from_count_change; end
|
||||
|
||||
sig { returns(T.nilable([T.nilable(::Integer), T.nilable(::Integer)])) }
|
||||
def user_user_follows_from_count_change_to_be_saved; end
|
||||
|
||||
sig { params(from: T.nilable(::Integer), to: T.nilable(::Integer)).returns(T::Boolean) }
|
||||
def user_user_follows_from_count_changed?(from: T.unsafe(nil), to: T.unsafe(nil)); end
|
||||
|
||||
sig { returns(T.nilable(::Integer)) }
|
||||
def user_user_follows_from_count_in_database; end
|
||||
|
||||
sig { returns(T.nilable([T.nilable(::Integer), T.nilable(::Integer)])) }
|
||||
def user_user_follows_from_count_previous_change; end
|
||||
|
||||
sig { params(from: T.nilable(::Integer), to: T.nilable(::Integer)).returns(T::Boolean) }
|
||||
def user_user_follows_from_count_previously_changed?(from: T.unsafe(nil), to: T.unsafe(nil)); end
|
||||
|
||||
sig { returns(T.nilable(::Integer)) }
|
||||
def user_user_follows_from_count_previously_was; end
|
||||
|
||||
sig { returns(T.nilable(::Integer)) }
|
||||
def user_user_follows_from_count_was; end
|
||||
|
||||
sig { void }
|
||||
def user_user_follows_from_count_will_change!; end
|
||||
|
||||
sig { returns(T.nilable(::Integer)) }
|
||||
def user_user_follows_to_count; end
|
||||
|
||||
sig { params(value: T.nilable(::Integer)).returns(T.nilable(::Integer)) }
|
||||
def user_user_follows_to_count=(value); end
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def user_user_follows_to_count?; end
|
||||
|
||||
sig { returns(T.nilable(::Integer)) }
|
||||
def user_user_follows_to_count_before_last_save; end
|
||||
|
||||
sig { returns(T.untyped) }
|
||||
def user_user_follows_to_count_before_type_cast; end
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def user_user_follows_to_count_came_from_user?; end
|
||||
|
||||
sig { returns(T.nilable([T.nilable(::Integer), T.nilable(::Integer)])) }
|
||||
def user_user_follows_to_count_change; end
|
||||
|
||||
sig { returns(T.nilable([T.nilable(::Integer), T.nilable(::Integer)])) }
|
||||
def user_user_follows_to_count_change_to_be_saved; end
|
||||
|
||||
sig { params(from: T.nilable(::Integer), to: T.nilable(::Integer)).returns(T::Boolean) }
|
||||
def user_user_follows_to_count_changed?(from: T.unsafe(nil), to: T.unsafe(nil)); end
|
||||
|
||||
sig { returns(T.nilable(::Integer)) }
|
||||
def user_user_follows_to_count_in_database; end
|
||||
|
||||
sig { returns(T.nilable([T.nilable(::Integer), T.nilable(::Integer)])) }
|
||||
def user_user_follows_to_count_previous_change; end
|
||||
|
||||
sig { params(from: T.nilable(::Integer), to: T.nilable(::Integer)).returns(T::Boolean) }
|
||||
def user_user_follows_to_count_previously_changed?(from: T.unsafe(nil), to: T.unsafe(nil)); end
|
||||
|
||||
sig { returns(T.nilable(::Integer)) }
|
||||
def user_user_follows_to_count_previously_was; end
|
||||
|
||||
sig { returns(T.nilable(::Integer)) }
|
||||
def user_user_follows_to_count_was; end
|
||||
|
||||
sig { void }
|
||||
def user_user_follows_to_count_will_change!; end
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def will_save_change_to_created_at?; end
|
||||
|
||||
@@ -1168,6 +1384,18 @@ class Domain::User
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def will_save_change_to_updated_at?; end
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def will_save_change_to_user_post_creations_count?; end
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def will_save_change_to_user_post_favs_count?; end
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def will_save_change_to_user_user_follows_from_count?; end
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def will_save_change_to_user_user_follows_to_count?; end
|
||||
end
|
||||
|
||||
module GeneratedRelationMethods
|
||||
|
||||
228
sorbet/rbi/dsl/domain/user/e621_user.rbi
generated
228
sorbet/rbi/dsl/domain/user/e621_user.rbi
generated
@@ -1341,6 +1341,18 @@ class Domain::User::E621User
|
||||
sig { void }
|
||||
def restore_updated_at!; end
|
||||
|
||||
sig { void }
|
||||
def restore_user_post_creations_count!; end
|
||||
|
||||
sig { void }
|
||||
def restore_user_post_favs_count!; end
|
||||
|
||||
sig { void }
|
||||
def restore_user_user_follows_from_count!; end
|
||||
|
||||
sig { void }
|
||||
def restore_user_user_follows_to_count!; end
|
||||
|
||||
sig { returns(T.nilable([T.nilable(::ActiveSupport::TimeWithZone), T.nilable(::ActiveSupport::TimeWithZone)])) }
|
||||
def saved_change_to_created_at; end
|
||||
|
||||
@@ -1425,6 +1437,30 @@ class Domain::User::E621User
|
||||
sig { returns(T::Boolean) }
|
||||
def saved_change_to_updated_at?; end
|
||||
|
||||
sig { returns(T.nilable([T.nilable(::Integer), T.nilable(::Integer)])) }
|
||||
def saved_change_to_user_post_creations_count; end
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def saved_change_to_user_post_creations_count?; end
|
||||
|
||||
sig { returns(T.nilable([T.nilable(::Integer), T.nilable(::Integer)])) }
|
||||
def saved_change_to_user_post_favs_count; end
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def saved_change_to_user_post_favs_count?; end
|
||||
|
||||
sig { returns(T.nilable([T.nilable(::Integer), T.nilable(::Integer)])) }
|
||||
def saved_change_to_user_user_follows_from_count; end
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def saved_change_to_user_user_follows_from_count?; end
|
||||
|
||||
sig { returns(T.nilable([T.nilable(::Integer), T.nilable(::Integer)])) }
|
||||
def saved_change_to_user_user_follows_to_count; end
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def saved_change_to_user_user_follows_to_count?; end
|
||||
|
||||
sig { returns(T.nilable(::ActiveSupport::TimeWithZone)) }
|
||||
def scanned_favs_at; end
|
||||
|
||||
@@ -1635,6 +1671,186 @@ class Domain::User::E621User
|
||||
sig { void }
|
||||
def updated_at_will_change!; end
|
||||
|
||||
sig { returns(T.nilable(::Integer)) }
|
||||
def user_post_creations_count; end
|
||||
|
||||
sig { params(value: T.nilable(::Integer)).returns(T.nilable(::Integer)) }
|
||||
def user_post_creations_count=(value); end
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def user_post_creations_count?; end
|
||||
|
||||
sig { returns(T.nilable(::Integer)) }
|
||||
def user_post_creations_count_before_last_save; end
|
||||
|
||||
sig { returns(T.untyped) }
|
||||
def user_post_creations_count_before_type_cast; end
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def user_post_creations_count_came_from_user?; end
|
||||
|
||||
sig { returns(T.nilable([T.nilable(::Integer), T.nilable(::Integer)])) }
|
||||
def user_post_creations_count_change; end
|
||||
|
||||
sig { returns(T.nilable([T.nilable(::Integer), T.nilable(::Integer)])) }
|
||||
def user_post_creations_count_change_to_be_saved; end
|
||||
|
||||
sig { params(from: T.nilable(::Integer), to: T.nilable(::Integer)).returns(T::Boolean) }
|
||||
def user_post_creations_count_changed?(from: T.unsafe(nil), to: T.unsafe(nil)); end
|
||||
|
||||
sig { returns(T.nilable(::Integer)) }
|
||||
def user_post_creations_count_in_database; end
|
||||
|
||||
sig { returns(T.nilable([T.nilable(::Integer), T.nilable(::Integer)])) }
|
||||
def user_post_creations_count_previous_change; end
|
||||
|
||||
sig { params(from: T.nilable(::Integer), to: T.nilable(::Integer)).returns(T::Boolean) }
|
||||
def user_post_creations_count_previously_changed?(from: T.unsafe(nil), to: T.unsafe(nil)); end
|
||||
|
||||
sig { returns(T.nilable(::Integer)) }
|
||||
def user_post_creations_count_previously_was; end
|
||||
|
||||
sig { returns(T.nilable(::Integer)) }
|
||||
def user_post_creations_count_was; end
|
||||
|
||||
sig { void }
|
||||
def user_post_creations_count_will_change!; end
|
||||
|
||||
sig { returns(T.nilable(::Integer)) }
|
||||
def user_post_favs_count; end
|
||||
|
||||
sig { params(value: T.nilable(::Integer)).returns(T.nilable(::Integer)) }
|
||||
def user_post_favs_count=(value); end
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def user_post_favs_count?; end
|
||||
|
||||
sig { returns(T.nilable(::Integer)) }
|
||||
def user_post_favs_count_before_last_save; end
|
||||
|
||||
sig { returns(T.untyped) }
|
||||
def user_post_favs_count_before_type_cast; end
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def user_post_favs_count_came_from_user?; end
|
||||
|
||||
sig { returns(T.nilable([T.nilable(::Integer), T.nilable(::Integer)])) }
|
||||
def user_post_favs_count_change; end
|
||||
|
||||
sig { returns(T.nilable([T.nilable(::Integer), T.nilable(::Integer)])) }
|
||||
def user_post_favs_count_change_to_be_saved; end
|
||||
|
||||
sig { params(from: T.nilable(::Integer), to: T.nilable(::Integer)).returns(T::Boolean) }
|
||||
def user_post_favs_count_changed?(from: T.unsafe(nil), to: T.unsafe(nil)); end
|
||||
|
||||
sig { returns(T.nilable(::Integer)) }
|
||||
def user_post_favs_count_in_database; end
|
||||
|
||||
sig { returns(T.nilable([T.nilable(::Integer), T.nilable(::Integer)])) }
|
||||
def user_post_favs_count_previous_change; end
|
||||
|
||||
sig { params(from: T.nilable(::Integer), to: T.nilable(::Integer)).returns(T::Boolean) }
|
||||
def user_post_favs_count_previously_changed?(from: T.unsafe(nil), to: T.unsafe(nil)); end
|
||||
|
||||
sig { returns(T.nilable(::Integer)) }
|
||||
def user_post_favs_count_previously_was; end
|
||||
|
||||
sig { returns(T.nilable(::Integer)) }
|
||||
def user_post_favs_count_was; end
|
||||
|
||||
sig { void }
|
||||
def user_post_favs_count_will_change!; end
|
||||
|
||||
sig { returns(T.nilable(::Integer)) }
|
||||
def user_user_follows_from_count; end
|
||||
|
||||
sig { params(value: T.nilable(::Integer)).returns(T.nilable(::Integer)) }
|
||||
def user_user_follows_from_count=(value); end
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def user_user_follows_from_count?; end
|
||||
|
||||
sig { returns(T.nilable(::Integer)) }
|
||||
def user_user_follows_from_count_before_last_save; end
|
||||
|
||||
sig { returns(T.untyped) }
|
||||
def user_user_follows_from_count_before_type_cast; end
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def user_user_follows_from_count_came_from_user?; end
|
||||
|
||||
sig { returns(T.nilable([T.nilable(::Integer), T.nilable(::Integer)])) }
|
||||
def user_user_follows_from_count_change; end
|
||||
|
||||
sig { returns(T.nilable([T.nilable(::Integer), T.nilable(::Integer)])) }
|
||||
def user_user_follows_from_count_change_to_be_saved; end
|
||||
|
||||
sig { params(from: T.nilable(::Integer), to: T.nilable(::Integer)).returns(T::Boolean) }
|
||||
def user_user_follows_from_count_changed?(from: T.unsafe(nil), to: T.unsafe(nil)); end
|
||||
|
||||
sig { returns(T.nilable(::Integer)) }
|
||||
def user_user_follows_from_count_in_database; end
|
||||
|
||||
sig { returns(T.nilable([T.nilable(::Integer), T.nilable(::Integer)])) }
|
||||
def user_user_follows_from_count_previous_change; end
|
||||
|
||||
sig { params(from: T.nilable(::Integer), to: T.nilable(::Integer)).returns(T::Boolean) }
|
||||
def user_user_follows_from_count_previously_changed?(from: T.unsafe(nil), to: T.unsafe(nil)); end
|
||||
|
||||
sig { returns(T.nilable(::Integer)) }
|
||||
def user_user_follows_from_count_previously_was; end
|
||||
|
||||
sig { returns(T.nilable(::Integer)) }
|
||||
def user_user_follows_from_count_was; end
|
||||
|
||||
sig { void }
|
||||
def user_user_follows_from_count_will_change!; end
|
||||
|
||||
sig { returns(T.nilable(::Integer)) }
|
||||
def user_user_follows_to_count; end
|
||||
|
||||
sig { params(value: T.nilable(::Integer)).returns(T.nilable(::Integer)) }
|
||||
def user_user_follows_to_count=(value); end
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def user_user_follows_to_count?; end
|
||||
|
||||
sig { returns(T.nilable(::Integer)) }
|
||||
def user_user_follows_to_count_before_last_save; end
|
||||
|
||||
sig { returns(T.untyped) }
|
||||
def user_user_follows_to_count_before_type_cast; end
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def user_user_follows_to_count_came_from_user?; end
|
||||
|
||||
sig { returns(T.nilable([T.nilable(::Integer), T.nilable(::Integer)])) }
|
||||
def user_user_follows_to_count_change; end
|
||||
|
||||
sig { returns(T.nilable([T.nilable(::Integer), T.nilable(::Integer)])) }
|
||||
def user_user_follows_to_count_change_to_be_saved; end
|
||||
|
||||
sig { params(from: T.nilable(::Integer), to: T.nilable(::Integer)).returns(T::Boolean) }
|
||||
def user_user_follows_to_count_changed?(from: T.unsafe(nil), to: T.unsafe(nil)); end
|
||||
|
||||
sig { returns(T.nilable(::Integer)) }
|
||||
def user_user_follows_to_count_in_database; end
|
||||
|
||||
sig { returns(T.nilable([T.nilable(::Integer), T.nilable(::Integer)])) }
|
||||
def user_user_follows_to_count_previous_change; end
|
||||
|
||||
sig { params(from: T.nilable(::Integer), to: T.nilable(::Integer)).returns(T::Boolean) }
|
||||
def user_user_follows_to_count_previously_changed?(from: T.unsafe(nil), to: T.unsafe(nil)); end
|
||||
|
||||
sig { returns(T.nilable(::Integer)) }
|
||||
def user_user_follows_to_count_previously_was; end
|
||||
|
||||
sig { returns(T.nilable(::Integer)) }
|
||||
def user_user_follows_to_count_was; end
|
||||
|
||||
sig { void }
|
||||
def user_user_follows_to_count_will_change!; end
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def will_save_change_to_created_at?; end
|
||||
|
||||
@@ -1676,6 +1892,18 @@ class Domain::User::E621User
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def will_save_change_to_updated_at?; end
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def will_save_change_to_user_post_creations_count?; end
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def will_save_change_to_user_post_favs_count?; end
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def will_save_change_to_user_user_follows_from_count?; end
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def will_save_change_to_user_user_follows_to_count?; end
|
||||
end
|
||||
|
||||
module GeneratedRelationMethods
|
||||
|
||||
228
sorbet/rbi/dsl/domain/user/fa_user.rbi
generated
228
sorbet/rbi/dsl/domain/user/fa_user.rbi
generated
@@ -2156,6 +2156,18 @@ class Domain::User::FaUser
|
||||
sig { void }
|
||||
def restore_url_name!; end
|
||||
|
||||
sig { void }
|
||||
def restore_user_post_creations_count!; end
|
||||
|
||||
sig { void }
|
||||
def restore_user_post_favs_count!; end
|
||||
|
||||
sig { void }
|
||||
def restore_user_user_follows_from_count!; end
|
||||
|
||||
sig { void }
|
||||
def restore_user_user_follows_to_count!; end
|
||||
|
||||
sig { returns(T.nilable([T.nilable(::String), T.nilable(::String)])) }
|
||||
def saved_change_to_account_status; end
|
||||
|
||||
@@ -2366,6 +2378,30 @@ class Domain::User::FaUser
|
||||
sig { returns(T::Boolean) }
|
||||
def saved_change_to_url_name?; end
|
||||
|
||||
sig { returns(T.nilable([T.nilable(::Integer), T.nilable(::Integer)])) }
|
||||
def saved_change_to_user_post_creations_count; end
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def saved_change_to_user_post_creations_count?; end
|
||||
|
||||
sig { returns(T.nilable([T.nilable(::Integer), T.nilable(::Integer)])) }
|
||||
def saved_change_to_user_post_favs_count; end
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def saved_change_to_user_post_favs_count?; end
|
||||
|
||||
sig { returns(T.nilable([T.nilable(::Integer), T.nilable(::Integer)])) }
|
||||
def saved_change_to_user_user_follows_from_count; end
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def saved_change_to_user_user_follows_from_count?; end
|
||||
|
||||
sig { returns(T.nilable([T.nilable(::Integer), T.nilable(::Integer)])) }
|
||||
def saved_change_to_user_user_follows_to_count; end
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def saved_change_to_user_user_follows_to_count?; end
|
||||
|
||||
sig { returns(T.nilable(::ActiveSupport::TimeWithZone)) }
|
||||
def scanned_favs_at; end
|
||||
|
||||
@@ -2896,6 +2932,186 @@ class Domain::User::FaUser
|
||||
sig { void }
|
||||
def url_name_will_change!; end
|
||||
|
||||
sig { returns(T.nilable(::Integer)) }
|
||||
def user_post_creations_count; end
|
||||
|
||||
sig { params(value: T.nilable(::Integer)).returns(T.nilable(::Integer)) }
|
||||
def user_post_creations_count=(value); end
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def user_post_creations_count?; end
|
||||
|
||||
sig { returns(T.nilable(::Integer)) }
|
||||
def user_post_creations_count_before_last_save; end
|
||||
|
||||
sig { returns(T.untyped) }
|
||||
def user_post_creations_count_before_type_cast; end
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def user_post_creations_count_came_from_user?; end
|
||||
|
||||
sig { returns(T.nilable([T.nilable(::Integer), T.nilable(::Integer)])) }
|
||||
def user_post_creations_count_change; end
|
||||
|
||||
sig { returns(T.nilable([T.nilable(::Integer), T.nilable(::Integer)])) }
|
||||
def user_post_creations_count_change_to_be_saved; end
|
||||
|
||||
sig { params(from: T.nilable(::Integer), to: T.nilable(::Integer)).returns(T::Boolean) }
|
||||
def user_post_creations_count_changed?(from: T.unsafe(nil), to: T.unsafe(nil)); end
|
||||
|
||||
sig { returns(T.nilable(::Integer)) }
|
||||
def user_post_creations_count_in_database; end
|
||||
|
||||
sig { returns(T.nilable([T.nilable(::Integer), T.nilable(::Integer)])) }
|
||||
def user_post_creations_count_previous_change; end
|
||||
|
||||
sig { params(from: T.nilable(::Integer), to: T.nilable(::Integer)).returns(T::Boolean) }
|
||||
def user_post_creations_count_previously_changed?(from: T.unsafe(nil), to: T.unsafe(nil)); end
|
||||
|
||||
sig { returns(T.nilable(::Integer)) }
|
||||
def user_post_creations_count_previously_was; end
|
||||
|
||||
sig { returns(T.nilable(::Integer)) }
|
||||
def user_post_creations_count_was; end
|
||||
|
||||
sig { void }
|
||||
def user_post_creations_count_will_change!; end
|
||||
|
||||
sig { returns(T.nilable(::Integer)) }
|
||||
def user_post_favs_count; end
|
||||
|
||||
sig { params(value: T.nilable(::Integer)).returns(T.nilable(::Integer)) }
|
||||
def user_post_favs_count=(value); end
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def user_post_favs_count?; end
|
||||
|
||||
sig { returns(T.nilable(::Integer)) }
|
||||
def user_post_favs_count_before_last_save; end
|
||||
|
||||
sig { returns(T.untyped) }
|
||||
def user_post_favs_count_before_type_cast; end
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def user_post_favs_count_came_from_user?; end
|
||||
|
||||
sig { returns(T.nilable([T.nilable(::Integer), T.nilable(::Integer)])) }
|
||||
def user_post_favs_count_change; end
|
||||
|
||||
sig { returns(T.nilable([T.nilable(::Integer), T.nilable(::Integer)])) }
|
||||
def user_post_favs_count_change_to_be_saved; end
|
||||
|
||||
sig { params(from: T.nilable(::Integer), to: T.nilable(::Integer)).returns(T::Boolean) }
|
||||
def user_post_favs_count_changed?(from: T.unsafe(nil), to: T.unsafe(nil)); end
|
||||
|
||||
sig { returns(T.nilable(::Integer)) }
|
||||
def user_post_favs_count_in_database; end
|
||||
|
||||
sig { returns(T.nilable([T.nilable(::Integer), T.nilable(::Integer)])) }
|
||||
def user_post_favs_count_previous_change; end
|
||||
|
||||
sig { params(from: T.nilable(::Integer), to: T.nilable(::Integer)).returns(T::Boolean) }
|
||||
def user_post_favs_count_previously_changed?(from: T.unsafe(nil), to: T.unsafe(nil)); end
|
||||
|
||||
sig { returns(T.nilable(::Integer)) }
|
||||
def user_post_favs_count_previously_was; end
|
||||
|
||||
sig { returns(T.nilable(::Integer)) }
|
||||
def user_post_favs_count_was; end
|
||||
|
||||
sig { void }
|
||||
def user_post_favs_count_will_change!; end
|
||||
|
||||
sig { returns(T.nilable(::Integer)) }
|
||||
def user_user_follows_from_count; end
|
||||
|
||||
sig { params(value: T.nilable(::Integer)).returns(T.nilable(::Integer)) }
|
||||
def user_user_follows_from_count=(value); end
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def user_user_follows_from_count?; end
|
||||
|
||||
sig { returns(T.nilable(::Integer)) }
|
||||
def user_user_follows_from_count_before_last_save; end
|
||||
|
||||
sig { returns(T.untyped) }
|
||||
def user_user_follows_from_count_before_type_cast; end
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def user_user_follows_from_count_came_from_user?; end
|
||||
|
||||
sig { returns(T.nilable([T.nilable(::Integer), T.nilable(::Integer)])) }
|
||||
def user_user_follows_from_count_change; end
|
||||
|
||||
sig { returns(T.nilable([T.nilable(::Integer), T.nilable(::Integer)])) }
|
||||
def user_user_follows_from_count_change_to_be_saved; end
|
||||
|
||||
sig { params(from: T.nilable(::Integer), to: T.nilable(::Integer)).returns(T::Boolean) }
|
||||
def user_user_follows_from_count_changed?(from: T.unsafe(nil), to: T.unsafe(nil)); end
|
||||
|
||||
sig { returns(T.nilable(::Integer)) }
|
||||
def user_user_follows_from_count_in_database; end
|
||||
|
||||
sig { returns(T.nilable([T.nilable(::Integer), T.nilable(::Integer)])) }
|
||||
def user_user_follows_from_count_previous_change; end
|
||||
|
||||
sig { params(from: T.nilable(::Integer), to: T.nilable(::Integer)).returns(T::Boolean) }
|
||||
def user_user_follows_from_count_previously_changed?(from: T.unsafe(nil), to: T.unsafe(nil)); end
|
||||
|
||||
sig { returns(T.nilable(::Integer)) }
|
||||
def user_user_follows_from_count_previously_was; end
|
||||
|
||||
sig { returns(T.nilable(::Integer)) }
|
||||
def user_user_follows_from_count_was; end
|
||||
|
||||
sig { void }
|
||||
def user_user_follows_from_count_will_change!; end
|
||||
|
||||
sig { returns(T.nilable(::Integer)) }
|
||||
def user_user_follows_to_count; end
|
||||
|
||||
sig { params(value: T.nilable(::Integer)).returns(T.nilable(::Integer)) }
|
||||
def user_user_follows_to_count=(value); end
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def user_user_follows_to_count?; end
|
||||
|
||||
sig { returns(T.nilable(::Integer)) }
|
||||
def user_user_follows_to_count_before_last_save; end
|
||||
|
||||
sig { returns(T.untyped) }
|
||||
def user_user_follows_to_count_before_type_cast; end
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def user_user_follows_to_count_came_from_user?; end
|
||||
|
||||
sig { returns(T.nilable([T.nilable(::Integer), T.nilable(::Integer)])) }
|
||||
def user_user_follows_to_count_change; end
|
||||
|
||||
sig { returns(T.nilable([T.nilable(::Integer), T.nilable(::Integer)])) }
|
||||
def user_user_follows_to_count_change_to_be_saved; end
|
||||
|
||||
sig { params(from: T.nilable(::Integer), to: T.nilable(::Integer)).returns(T::Boolean) }
|
||||
def user_user_follows_to_count_changed?(from: T.unsafe(nil), to: T.unsafe(nil)); end
|
||||
|
||||
sig { returns(T.nilable(::Integer)) }
|
||||
def user_user_follows_to_count_in_database; end
|
||||
|
||||
sig { returns(T.nilable([T.nilable(::Integer), T.nilable(::Integer)])) }
|
||||
def user_user_follows_to_count_previous_change; end
|
||||
|
||||
sig { params(from: T.nilable(::Integer), to: T.nilable(::Integer)).returns(T::Boolean) }
|
||||
def user_user_follows_to_count_previously_changed?(from: T.unsafe(nil), to: T.unsafe(nil)); end
|
||||
|
||||
sig { returns(T.nilable(::Integer)) }
|
||||
def user_user_follows_to_count_previously_was; end
|
||||
|
||||
sig { returns(T.nilable(::Integer)) }
|
||||
def user_user_follows_to_count_was; end
|
||||
|
||||
sig { void }
|
||||
def user_user_follows_to_count_will_change!; end
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def will_save_change_to_account_status?; end
|
||||
|
||||
@@ -3000,6 +3216,18 @@ class Domain::User::FaUser
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def will_save_change_to_url_name?; end
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def will_save_change_to_user_post_creations_count?; end
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def will_save_change_to_user_post_favs_count?; end
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def will_save_change_to_user_user_follows_from_count?; end
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def will_save_change_to_user_user_follows_to_count?; end
|
||||
end
|
||||
|
||||
module GeneratedRelationMethods
|
||||
|
||||
228
sorbet/rbi/dsl/domain/user/inkbunny_user.rbi
generated
228
sorbet/rbi/dsl/domain/user/inkbunny_user.rbi
generated
@@ -1298,6 +1298,18 @@ class Domain::User::InkbunnyUser
|
||||
sig { void }
|
||||
def restore_updated_at!; end
|
||||
|
||||
sig { void }
|
||||
def restore_user_post_creations_count!; end
|
||||
|
||||
sig { void }
|
||||
def restore_user_post_favs_count!; end
|
||||
|
||||
sig { void }
|
||||
def restore_user_user_follows_from_count!; end
|
||||
|
||||
sig { void }
|
||||
def restore_user_user_follows_to_count!; end
|
||||
|
||||
sig { returns(T.nilable([T.nilable(::ActiveSupport::TimeWithZone), T.nilable(::ActiveSupport::TimeWithZone)])) }
|
||||
def saved_change_to_created_at; end
|
||||
|
||||
@@ -1382,6 +1394,30 @@ class Domain::User::InkbunnyUser
|
||||
sig { returns(T::Boolean) }
|
||||
def saved_change_to_updated_at?; end
|
||||
|
||||
sig { returns(T.nilable([T.nilable(::Integer), T.nilable(::Integer)])) }
|
||||
def saved_change_to_user_post_creations_count; end
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def saved_change_to_user_post_creations_count?; end
|
||||
|
||||
sig { returns(T.nilable([T.nilable(::Integer), T.nilable(::Integer)])) }
|
||||
def saved_change_to_user_post_favs_count; end
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def saved_change_to_user_post_favs_count?; end
|
||||
|
||||
sig { returns(T.nilable([T.nilable(::Integer), T.nilable(::Integer)])) }
|
||||
def saved_change_to_user_user_follows_from_count; end
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def saved_change_to_user_user_follows_from_count?; end
|
||||
|
||||
sig { returns(T.nilable([T.nilable(::Integer), T.nilable(::Integer)])) }
|
||||
def saved_change_to_user_user_follows_to_count; end
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def saved_change_to_user_user_follows_to_count?; end
|
||||
|
||||
sig { returns(T.nilable(::ActiveSupport::TimeWithZone)) }
|
||||
def scanned_gallery_at; end
|
||||
|
||||
@@ -1627,6 +1663,186 @@ class Domain::User::InkbunnyUser
|
||||
sig { void }
|
||||
def updated_at_will_change!; end
|
||||
|
||||
sig { returns(T.nilable(::Integer)) }
|
||||
def user_post_creations_count; end
|
||||
|
||||
sig { params(value: T.nilable(::Integer)).returns(T.nilable(::Integer)) }
|
||||
def user_post_creations_count=(value); end
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def user_post_creations_count?; end
|
||||
|
||||
sig { returns(T.nilable(::Integer)) }
|
||||
def user_post_creations_count_before_last_save; end
|
||||
|
||||
sig { returns(T.untyped) }
|
||||
def user_post_creations_count_before_type_cast; end
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def user_post_creations_count_came_from_user?; end
|
||||
|
||||
sig { returns(T.nilable([T.nilable(::Integer), T.nilable(::Integer)])) }
|
||||
def user_post_creations_count_change; end
|
||||
|
||||
sig { returns(T.nilable([T.nilable(::Integer), T.nilable(::Integer)])) }
|
||||
def user_post_creations_count_change_to_be_saved; end
|
||||
|
||||
sig { params(from: T.nilable(::Integer), to: T.nilable(::Integer)).returns(T::Boolean) }
|
||||
def user_post_creations_count_changed?(from: T.unsafe(nil), to: T.unsafe(nil)); end
|
||||
|
||||
sig { returns(T.nilable(::Integer)) }
|
||||
def user_post_creations_count_in_database; end
|
||||
|
||||
sig { returns(T.nilable([T.nilable(::Integer), T.nilable(::Integer)])) }
|
||||
def user_post_creations_count_previous_change; end
|
||||
|
||||
sig { params(from: T.nilable(::Integer), to: T.nilable(::Integer)).returns(T::Boolean) }
|
||||
def user_post_creations_count_previously_changed?(from: T.unsafe(nil), to: T.unsafe(nil)); end
|
||||
|
||||
sig { returns(T.nilable(::Integer)) }
|
||||
def user_post_creations_count_previously_was; end
|
||||
|
||||
sig { returns(T.nilable(::Integer)) }
|
||||
def user_post_creations_count_was; end
|
||||
|
||||
sig { void }
|
||||
def user_post_creations_count_will_change!; end
|
||||
|
||||
sig { returns(T.nilable(::Integer)) }
|
||||
def user_post_favs_count; end
|
||||
|
||||
sig { params(value: T.nilable(::Integer)).returns(T.nilable(::Integer)) }
|
||||
def user_post_favs_count=(value); end
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def user_post_favs_count?; end
|
||||
|
||||
sig { returns(T.nilable(::Integer)) }
|
||||
def user_post_favs_count_before_last_save; end
|
||||
|
||||
sig { returns(T.untyped) }
|
||||
def user_post_favs_count_before_type_cast; end
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def user_post_favs_count_came_from_user?; end
|
||||
|
||||
sig { returns(T.nilable([T.nilable(::Integer), T.nilable(::Integer)])) }
|
||||
def user_post_favs_count_change; end
|
||||
|
||||
sig { returns(T.nilable([T.nilable(::Integer), T.nilable(::Integer)])) }
|
||||
def user_post_favs_count_change_to_be_saved; end
|
||||
|
||||
sig { params(from: T.nilable(::Integer), to: T.nilable(::Integer)).returns(T::Boolean) }
|
||||
def user_post_favs_count_changed?(from: T.unsafe(nil), to: T.unsafe(nil)); end
|
||||
|
||||
sig { returns(T.nilable(::Integer)) }
|
||||
def user_post_favs_count_in_database; end
|
||||
|
||||
sig { returns(T.nilable([T.nilable(::Integer), T.nilable(::Integer)])) }
|
||||
def user_post_favs_count_previous_change; end
|
||||
|
||||
sig { params(from: T.nilable(::Integer), to: T.nilable(::Integer)).returns(T::Boolean) }
|
||||
def user_post_favs_count_previously_changed?(from: T.unsafe(nil), to: T.unsafe(nil)); end
|
||||
|
||||
sig { returns(T.nilable(::Integer)) }
|
||||
def user_post_favs_count_previously_was; end
|
||||
|
||||
sig { returns(T.nilable(::Integer)) }
|
||||
def user_post_favs_count_was; end
|
||||
|
||||
sig { void }
|
||||
def user_post_favs_count_will_change!; end
|
||||
|
||||
sig { returns(T.nilable(::Integer)) }
|
||||
def user_user_follows_from_count; end
|
||||
|
||||
sig { params(value: T.nilable(::Integer)).returns(T.nilable(::Integer)) }
|
||||
def user_user_follows_from_count=(value); end
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def user_user_follows_from_count?; end
|
||||
|
||||
sig { returns(T.nilable(::Integer)) }
|
||||
def user_user_follows_from_count_before_last_save; end
|
||||
|
||||
sig { returns(T.untyped) }
|
||||
def user_user_follows_from_count_before_type_cast; end
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def user_user_follows_from_count_came_from_user?; end
|
||||
|
||||
sig { returns(T.nilable([T.nilable(::Integer), T.nilable(::Integer)])) }
|
||||
def user_user_follows_from_count_change; end
|
||||
|
||||
sig { returns(T.nilable([T.nilable(::Integer), T.nilable(::Integer)])) }
|
||||
def user_user_follows_from_count_change_to_be_saved; end
|
||||
|
||||
sig { params(from: T.nilable(::Integer), to: T.nilable(::Integer)).returns(T::Boolean) }
|
||||
def user_user_follows_from_count_changed?(from: T.unsafe(nil), to: T.unsafe(nil)); end
|
||||
|
||||
sig { returns(T.nilable(::Integer)) }
|
||||
def user_user_follows_from_count_in_database; end
|
||||
|
||||
sig { returns(T.nilable([T.nilable(::Integer), T.nilable(::Integer)])) }
|
||||
def user_user_follows_from_count_previous_change; end
|
||||
|
||||
sig { params(from: T.nilable(::Integer), to: T.nilable(::Integer)).returns(T::Boolean) }
|
||||
def user_user_follows_from_count_previously_changed?(from: T.unsafe(nil), to: T.unsafe(nil)); end
|
||||
|
||||
sig { returns(T.nilable(::Integer)) }
|
||||
def user_user_follows_from_count_previously_was; end
|
||||
|
||||
sig { returns(T.nilable(::Integer)) }
|
||||
def user_user_follows_from_count_was; end
|
||||
|
||||
sig { void }
|
||||
def user_user_follows_from_count_will_change!; end
|
||||
|
||||
sig { returns(T.nilable(::Integer)) }
|
||||
def user_user_follows_to_count; end
|
||||
|
||||
sig { params(value: T.nilable(::Integer)).returns(T.nilable(::Integer)) }
|
||||
def user_user_follows_to_count=(value); end
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def user_user_follows_to_count?; end
|
||||
|
||||
sig { returns(T.nilable(::Integer)) }
|
||||
def user_user_follows_to_count_before_last_save; end
|
||||
|
||||
sig { returns(T.untyped) }
|
||||
def user_user_follows_to_count_before_type_cast; end
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def user_user_follows_to_count_came_from_user?; end
|
||||
|
||||
sig { returns(T.nilable([T.nilable(::Integer), T.nilable(::Integer)])) }
|
||||
def user_user_follows_to_count_change; end
|
||||
|
||||
sig { returns(T.nilable([T.nilable(::Integer), T.nilable(::Integer)])) }
|
||||
def user_user_follows_to_count_change_to_be_saved; end
|
||||
|
||||
sig { params(from: T.nilable(::Integer), to: T.nilable(::Integer)).returns(T::Boolean) }
|
||||
def user_user_follows_to_count_changed?(from: T.unsafe(nil), to: T.unsafe(nil)); end
|
||||
|
||||
sig { returns(T.nilable(::Integer)) }
|
||||
def user_user_follows_to_count_in_database; end
|
||||
|
||||
sig { returns(T.nilable([T.nilable(::Integer), T.nilable(::Integer)])) }
|
||||
def user_user_follows_to_count_previous_change; end
|
||||
|
||||
sig { params(from: T.nilable(::Integer), to: T.nilable(::Integer)).returns(T::Boolean) }
|
||||
def user_user_follows_to_count_previously_changed?(from: T.unsafe(nil), to: T.unsafe(nil)); end
|
||||
|
||||
sig { returns(T.nilable(::Integer)) }
|
||||
def user_user_follows_to_count_previously_was; end
|
||||
|
||||
sig { returns(T.nilable(::Integer)) }
|
||||
def user_user_follows_to_count_was; end
|
||||
|
||||
sig { void }
|
||||
def user_user_follows_to_count_will_change!; end
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def will_save_change_to_created_at?; end
|
||||
|
||||
@@ -1668,6 +1884,18 @@ class Domain::User::InkbunnyUser
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def will_save_change_to_updated_at?; end
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def will_save_change_to_user_post_creations_count?; end
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def will_save_change_to_user_post_favs_count?; end
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def will_save_change_to_user_user_follows_from_count?; end
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def will_save_change_to_user_user_follows_to_count?; end
|
||||
end
|
||||
|
||||
module GeneratedRelationMethods
|
||||
|
||||
16
sorbet/rbi/dsl/scraper/generic_http_client_config.rbi
generated
Normal file
16
sorbet/rbi/dsl/scraper/generic_http_client_config.rbi
generated
Normal file
@@ -0,0 +1,16 @@
|
||||
# typed: true
|
||||
|
||||
# DO NOT EDIT MANUALLY
|
||||
# This is an autogenerated file for dynamic methods in `Scraper::GenericHttpClientConfig`.
|
||||
# Please instead update this file by running `bin/tapioca dsl Scraper::GenericHttpClientConfig`.
|
||||
|
||||
|
||||
class Scraper::GenericHttpClientConfig
|
||||
sig { returns(ColorLogger) }
|
||||
def logger; end
|
||||
|
||||
class << self
|
||||
sig { returns(ColorLogger) }
|
||||
def logger; end
|
||||
end
|
||||
end
|
||||
@@ -826,12 +826,12 @@ describe Domain::Fa::Job::UserPageJob do
|
||||
end
|
||||
end
|
||||
|
||||
context "user not found" do
|
||||
shared_examples "user not found" do |status_code|
|
||||
let(:client_mock_config) do
|
||||
[
|
||||
{
|
||||
uri: "https://www.furaffinity.net/user/onefatpokemon/",
|
||||
status_code: 200,
|
||||
status_code:,
|
||||
content_type: "text/html",
|
||||
contents:
|
||||
SpecUtil.read_fixture_file(
|
||||
@@ -855,4 +855,12 @@ describe Domain::Fa::Job::UserPageJob do
|
||||
expect(user.state).to eq("error")
|
||||
end
|
||||
end
|
||||
|
||||
context "user not found with 200 status code" do
|
||||
include_examples "user not found", 200
|
||||
end
|
||||
|
||||
context "user not found with 400 status code" do
|
||||
include_examples "user not found", 400
|
||||
end
|
||||
end
|
||||
|
||||
145
spec/models/domain/user_counter_cache_spec.rb
Normal file
145
spec/models/domain/user_counter_cache_spec.rb
Normal file
@@ -0,0 +1,145 @@
|
||||
# typed: false
|
||||
require "rails_helper"
|
||||
|
||||
RSpec.describe "Domain::User counter caches", type: :model do
|
||||
let(:user) { create(:domain_user_fa_user) }
|
||||
let(:post) { create(:domain_post_fa_post) }
|
||||
|
||||
describe "user_post_creations_count" do
|
||||
it "increments when a post creation is added" do
|
||||
expect {
|
||||
Domain::UserPostCreation.create!(user: user, post: post)
|
||||
}.to change { user.reload.user_post_creations_count }.from(0).to(1)
|
||||
end
|
||||
|
||||
it "decrements when a post creation is removed" do
|
||||
creation = Domain::UserPostCreation.create!(user: user, post: post)
|
||||
expect { creation.destroy }.to change {
|
||||
user.reload.user_post_creations_count
|
||||
}.from(1).to(0)
|
||||
end
|
||||
|
||||
it "provides direct access to the counts" do
|
||||
posts = create_list(:domain_post_fa_post, 3)
|
||||
posts.each { |p| Domain::UserPostCreation.create!(user: user, post: p) }
|
||||
|
||||
# Counter in database should be updated automatically
|
||||
expect(user.reload.user_post_creations_count).to eq(3)
|
||||
|
||||
# Calling the method should use the cached value
|
||||
expect(user.user_post_creations_count).to eq(3)
|
||||
end
|
||||
|
||||
it "resets to the correct count" do
|
||||
posts = create_list(:domain_post_fa_post, 3)
|
||||
posts.each { |p| Domain::UserPostCreation.create!(user: user, post: p) }
|
||||
|
||||
# Manually set to wrong value
|
||||
user.update_column(:user_post_creations_count, 0)
|
||||
expect(user.read_attribute(:user_post_creations_count)).to eq(0)
|
||||
|
||||
# Reset counter
|
||||
Domain::User.reset_counters(user.id, :user_post_creations)
|
||||
expect(user.reload.user_post_creations_count).to eq(3)
|
||||
end
|
||||
end
|
||||
|
||||
describe "user_post_favs_count" do
|
||||
it "increments when a post fav is added" do
|
||||
expect { Domain::UserPostFav.create!(user: user, post: post) }.to change {
|
||||
user.reload.user_post_favs_count
|
||||
}.from(0).to(1)
|
||||
end
|
||||
|
||||
it "decrements when a post fav is removed" do
|
||||
fav = Domain::UserPostFav.create!(user: user, post: post)
|
||||
expect { fav.destroy }.to change {
|
||||
user.reload.user_post_favs_count
|
||||
}.from(1).to(0)
|
||||
end
|
||||
|
||||
it "provides direct access to the counts" do
|
||||
posts = create_list(:domain_post_fa_post, 3)
|
||||
posts.each { |p| Domain::UserPostFav.create!(user: user, post: p) }
|
||||
|
||||
# Counter in database should be updated automatically
|
||||
expect(user.reload.user_post_favs_count).to eq(3)
|
||||
|
||||
# Calling the method should use the cached value
|
||||
expect(user.user_post_favs_count).to eq(3)
|
||||
end
|
||||
end
|
||||
|
||||
describe "user_user_follows_from_count" do
|
||||
let(:other_user) { create(:domain_user_fa_user) }
|
||||
|
||||
it "increments when a follow is added" do
|
||||
expect {
|
||||
Domain::UserUserFollow.create!(from: user, to: other_user)
|
||||
}.to change { user.reload.user_user_follows_from_count }.from(0).to(1)
|
||||
end
|
||||
|
||||
it "decrements when a follow is removed" do
|
||||
follow = Domain::UserUserFollow.create!(from: user, to: other_user)
|
||||
expect { follow.destroy }.to change {
|
||||
user.reload.user_user_follows_from_count
|
||||
}.from(1).to(0)
|
||||
end
|
||||
|
||||
it "provides direct access to the counts" do
|
||||
users = create_list(:domain_user_fa_user, 3)
|
||||
users.each { |u| Domain::UserUserFollow.create!(from: user, to: u) }
|
||||
|
||||
# Counter in database should be updated automatically
|
||||
expect(user.reload.user_user_follows_from_count).to eq(3)
|
||||
|
||||
# Calling the method should use the cached value
|
||||
expect(user.user_user_follows_from_count).to eq(3)
|
||||
end
|
||||
end
|
||||
|
||||
describe "user_user_follows_to_count" do
|
||||
let(:other_user) { create(:domain_user_fa_user) }
|
||||
|
||||
it "increments when a follow is added" do
|
||||
expect {
|
||||
Domain::UserUserFollow.create!(from: other_user, to: user)
|
||||
}.to change { user.reload.user_user_follows_to_count }.from(0).to(1)
|
||||
end
|
||||
|
||||
it "decrements when a follow is removed" do
|
||||
follow = Domain::UserUserFollow.create!(from: other_user, to: user)
|
||||
expect { follow.destroy }.to change {
|
||||
user.reload.user_user_follows_to_count
|
||||
}.from(1).to(0)
|
||||
end
|
||||
|
||||
it "provides direct access to the counts" do
|
||||
users = create_list(:domain_user_fa_user, 3)
|
||||
users.each { |u| Domain::UserUserFollow.create!(from: u, to: user) }
|
||||
|
||||
# Counter in database should be updated automatically
|
||||
expect(user.reload.user_user_follows_to_count).to eq(3)
|
||||
|
||||
# Calling the method should use the cached value
|
||||
expect(user.user_user_follows_to_count).to eq(3)
|
||||
end
|
||||
end
|
||||
|
||||
describe "counter cache consistency" do
|
||||
it "maintains separate counts for creations and favs" do
|
||||
# Create 2 posts and fav 3 posts
|
||||
created_posts = create_list(:domain_post_fa_post, 2)
|
||||
faved_posts = create_list(:domain_post_fa_post, 3)
|
||||
|
||||
created_posts.each do |p|
|
||||
Domain::UserPostCreation.create!(user: user, post: p)
|
||||
end
|
||||
faved_posts.each { |p| Domain::UserPostFav.create!(user: user, post: p) }
|
||||
|
||||
user.reload
|
||||
expect(user.user_post_creations_count).to eq(2)
|
||||
expect(user.user_post_favs_count).to eq(3)
|
||||
end
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user