migrate inkbunny to domain script

This commit is contained in:
Dylan Knutson
2025-02-05 17:13:00 +00:00
parent aea94c98cd
commit 35ba1db97e
42 changed files with 13674 additions and 1081 deletions

View File

@@ -3,6 +3,11 @@ class Domain::MigrateToDomain
extend T::Sig
include HasColorLogger
sig { params(pb_sink: IO).void }
def initialize(pb_sink = $stderr)
@pb_sink = pb_sink
end
sig { void }
def migrate_e621_users
logger.info "migrating e621 users"
@@ -15,7 +20,7 @@ class Domain::MigrateToDomain
throttle_rate: 0.2,
total: query.count,
format: "%t: %c/%C %B %p%% %a %e",
output: $stderr,
output: @pb_sink,
)
query.find_in_batches(batch_size: 10_000) do |batch|
migrate_batch(Domain::User::E621User, batch) do |old_model|
@@ -39,7 +44,7 @@ class Domain::MigrateToDomain
throttle_rate: 0.2,
total: query.count,
format: "%t: %c/%C %B %p%% %a %e",
output: $stderr,
output: @pb_sink,
)
query.find_in_batches(batch_size: 10_000) do |batch|
migrate_batch(Domain::Post::E621Post, batch) do |old_model|
@@ -64,12 +69,20 @@ class Domain::MigrateToDomain
throttle_rate: 0.2,
total: query.count,
format: "%t: %c/%C %B %p%% %a %e",
output: $stderr,
output: @pb_sink,
)
query.find_in_batches(batch_size: 10_000) do |batch|
migrate_batch(Domain::User::FaUser, batch) do |old_user|
initialize_fa_user_from(old_user)
models =
migrate_batch(Domain::User::FaUser, batch) do |old_user|
initialize_fa_user_from(old_user)
end
migrate_batch(Domain::UserAvatar, models.filter(&:avatar)) do |user|
avatar = T.must(user.avatar)
avatar.user_id = user.id
avatar
end
pb.progress = [pb.progress + batch.size, pb.total].min
end
end
@@ -77,44 +90,51 @@ class Domain::MigrateToDomain
sig { void }
def migrate_fa_posts
logger.info "migrating fa posts"
query =
Domain::Fa::Post.where.not(fa_id: Domain::Post::FaPost.select(:fa_id))
old_fa_ids = Domain::Fa::Post.pluck(:fa_id)
logger.info "old_fa_ids: #{old_fa_ids.size}"
new_fa_ids = Domain::Post::FaPost.pluck(:fa_id)
logger.info "new_fa_ids: #{new_fa_ids.size}"
missing_fa_ids = old_fa_ids - new_fa_ids
missing_fa_ids.sort!
logger.info "missing_fa_ids: #{missing_fa_ids.size}"
pb =
ProgressBar.create(
throttle_rate: 0.2,
total: query.count,
total: missing_fa_ids.count,
format: "%t: %c/%C %B %p%% %a %e",
output: $stderr,
output: @pb_sink,
)
query
.includes(:creator, :file)
.find_in_batches(batch_size: 10_000) do |batch|
ReduxApplicationRecord.transaction do
initialized_models =
migrate_batch(Domain::Post::FaPost, batch) do |old_post|
initialize_fa_post_from(old_post)
end
migrate_batch(
Domain::PostFile,
initialized_models.filter(&:file),
) do |post|
file = T.must(post.file)
file.post_id = post.id
file
missing_fa_ids.each_slice(10_000) do |fa_ids|
batch =
Domain::Fa::Post.where(fa_id: fa_ids).includes(:creator, :file).to_a
ReduxApplicationRecord.transaction do
initialized_models =
migrate_batch(Domain::Post::FaPost, batch) do |old_post|
initialize_fa_post_from(old_post)
end
migrate_batch(
Domain::UserPostCreation,
initialized_models.filter(&:user_post_creation),
) do |post|
user_post_creation = T.must(post.user_post_creation)
user_post_creation.post_id = post.id
user_post_creation
end
migrate_batch(
Domain::PostFile,
initialized_models.filter(&:file),
) do |post|
file = T.must(post.file)
file.post_id = post.id
file
end
migrate_batch(
Domain::UserPostCreation,
initialized_models.filter(&:primary_user_post_creation),
) do |post|
user_post_creation = T.must(post.primary_user_post_creation)
user_post_creation.post_id = post.id
user_post_creation
end
pb.progress = [pb.progress + batch.size, pb.total].min
end
pb.progress = [pb.progress + batch.size, pb.total].min
end
end
sig { void }
@@ -141,6 +161,210 @@ class Domain::MigrateToDomain
.find_each { |user| migrate_fa_user_followed_users(user) }
end
sig { void }
def migrate_inkbunny_users
logger.info "migrating inkbunny users"
query =
Domain::Inkbunny::User.where.not(
ib_user_id: Domain::User::InkbunnyUser.select(:ib_id),
)
pb =
ProgressBar.create(
throttle_rate: 0.2,
total: query.count,
format: "%t: %c/%C %B %p%% %a %e",
output: @pb_sink,
)
query.find_in_batches(batch_size: 10_000) do |batch|
ReduxApplicationRecord.transaction do
models =
migrate_batch(Domain::User::InkbunnyUser, batch) do |old_user|
initialize_inkbunny_user(old_user)
end
migrate_batch(Domain::UserAvatar, models.filter(&:avatar)) do |user|
avatar = T.must(user.avatar)
avatar.user_id = user.id
avatar
end
end
pb.progress = [pb.progress + batch.size, pb.total].min
end
end
sig { void }
def migrate_inkbunny_posts
logger.info "migrating inkbunny posts"
query =
Domain::Inkbunny::Post
.where.not(ib_post_id: Domain::Post::InkbunnyPost.select(:ib_id))
.includes(:creator, :files, :pools)
pb =
ProgressBar.create(
throttle_rate: 0.2,
total: query.count,
format: "%t: %c/%C %B %p%% %a %e",
output: @pb_sink,
)
query.find_in_batches(batch_size: 10_000) do |batch|
ReduxApplicationRecord.transaction do
models =
migrate_batch(Domain::Post::InkbunnyPost, batch) do |old_post|
initialize_inkbunny_post(old_post)
end
migrate_batch(
Domain::UserPostCreation,
models.filter(&:primary_user_post_creation),
) do |post|
user_post_creation = T.must(post.primary_user_post_creation)
user_post_creation.post_id = post.id
user_post_creation
end
models.each do |model|
model.files.each { |file| file.post_id = model.id }
end
migrate_batch(Domain::PostFile, models.flat_map(&:files)) do |file|
file
end
end
pb.progress = [pb.progress + batch.size, pb.total].min
end
end
sig { void }
def migrate_inkbunny_pools
logger.info "migrating inkbunny pools"
query =
Domain::Inkbunny::Pool
.where.not(ib_pool_id: Domain::PostGroup::InkbunnyPool.select(:ib_id))
.includes(pool_joins: %i[post left_post right_post])
pb =
ProgressBar.create(
throttle_rate: 0.2,
total: query.count,
format: "%t: %c/%C %B %p%% %a %e",
output: @pb_sink,
)
query.find_in_batches(batch_size: 10_000) do |batch|
ReduxApplicationRecord.transaction do
models =
migrate_batch(Domain::PostGroup::InkbunnyPool, batch) do |old_pool|
initialize_inkbunny_pool(old_pool)
end
models.each do |model|
model.post_group_joins.each do |post_group_join|
post_group_join.group_id = model.id
end
end
migrate_batch(
Domain::PostGroupJoin::InkbunnyPoolJoin,
models.flat_map(&:post_group_joins),
) { |post_group_join| post_group_join }
end
pb.progress = [pb.progress + batch.size, pb.total].min
end
end
sig do
params(old_user: Domain::Inkbunny::User).returns(Domain::User::InkbunnyUser)
end
def initialize_inkbunny_user(old_user)
new_user = Domain::User::InkbunnyUser.new
new_user.ib_id = old_user.ib_user_id
new_user.name = old_user.name
new_user.state = old_user.state
new_user.scanned_gallery_at = old_user.scanned_gallery_at
new_user.deep_update_log_entry_id = old_user.deep_update_log_entry_id
new_user.shallow_update_log_entry_id = old_user.shallow_update_log_entry_id
new_user.created_at = old_user.created_at
if old_avatar_log_entry = old_user.avatar_log_entry
new_avatar = Domain::UserAvatar.new
new_avatar.log_entry_id = old_avatar_log_entry.id
new_avatar.url_str = old_avatar_log_entry.uri_str
new_avatar.state =
old_avatar_log_entry.status_code == 200 ? "ok" : "error"
new_user.avatar = new_avatar
end
new_user
end
sig do
params(old_post: Domain::Inkbunny::Post).returns(Domain::Post::InkbunnyPost)
end
def initialize_inkbunny_post(old_post)
new_post = Domain::Post::InkbunnyPost.new
new_post.ib_id = old_post.ib_post_id
new_post.state = old_post.state
new_post.rating = old_post.rating
new_post.submission_type = old_post.submission_type
new_post.created_at = old_post.created_at
if old_creator = old_post.creator
new_post.creator =
Domain::User::InkbunnyUser.find_by!(ib_id: old_creator.ib_user_id)
end
new_post.files =
old_post.files.map do |old_file|
new_file = Domain::PostFile.new
new_file.log_entry_id = old_file.log_entry_id
new_file.url_str = old_file.url_str
new_file.state = old_file.state
new_file
end
new_post
end
sig do
params(old_pool: Domain::Inkbunny::Pool).returns(
Domain::PostGroup::InkbunnyPool,
)
end
def initialize_inkbunny_pool(old_pool)
new_pool = Domain::PostGroup::InkbunnyPool.new
new_pool.ib_id = old_pool.ib_pool_id
new_pool.post_group_joins =
old_pool.pool_joins.map do |old_pool_join|
new_pool_join = Domain::PostGroupJoin::InkbunnyPoolJoin.new
new_pool_join.post_id =
Domain::Post::InkbunnyPost.find_by!(
ib_id: T.must(old_pool_join.post).ib_post_id,
).id
if old_left_post = old_pool_join.left_post
new_pool_join.left_post_id =
Domain::Post::InkbunnyPost.find_by!(
ib_id: old_left_post.ib_post_id,
).id
end
if old_right_post = old_pool_join.right_post
new_pool_join.right_post_id =
Domain::Post::InkbunnyPost.find_by!(
ib_id: old_right_post.ib_post_id,
).id
end
new_pool_join
end
new_pool
end
private
sig { params(old_user: Domain::E621::User).returns(Domain::User::E621User) }
@@ -198,6 +422,22 @@ class Domain::MigrateToDomain
new_user.scanned_gallery_at = old_user.scanned_gallery_at
new_user.scanned_page_at = old_user.scanned_page_at
new_user.registered_at = old_user.registered_at
if old_avatar = old_user.avatar
new_avatar = Domain::UserAvatar.new
new_avatar.log_entry_id = old_avatar.log_entry_id
new_avatar.url_str = old_avatar.file_url_str
new_avatar.state =
case old_avatar.state
when "ok"
"ok"
else
new_avatar.error_message = old_avatar.state
"error"
end
new_user.avatar = new_avatar
end
new_user
end
@@ -232,14 +472,11 @@ class Domain::MigrateToDomain
end
if post.file.present?
new_post.file =
Domain::PostFile.find_or_initialize_by(
log_entry: post.file,
) do |new_file|
new_file.log_entry = post.file
new_file.url_str = post.file_url_str
new_file.state = post.state
end
new_file = Domain::PostFile.new
new_file.log_entry_id = post.file_id
new_file.url_str = post.file_url_str
new_file.state = post.state
new_post.file = new_file
end
new_post
end

View File

@@ -44,6 +44,8 @@ module ActiveRecord::QueryMethods
sig { params(field: T.untyped).returns(T.untyped) }
def arel_column(field)
klass = T.cast(T.unsafe(self).klass, T.class_of(ActiveRecord::Base))
is_order_field =
field.instance_variable_get("@_is_order_field") || false
if attribute_def =
AttrJsonRecordAliases::ImplHelper.get_json_attr_def(klass, field)
attr_type_cast =
@@ -51,14 +53,28 @@ module ActiveRecord::QueryMethods
adapter_class = T.unsafe(self).adapter_class
column =
"#{adapter_class.quote_column_name("json_attributes")}->>'#{field}'"
Arel::Nodes::SqlLiteral.new(
"(#{adapter_class.quote_table_name(klass.table_name)}.#{column})#{attr_type_cast} " +
"AS #{adapter_class.quote_column_name(field)}",
)
column_expr =
"(#{adapter_class.quote_table_name(klass.table_name)}.#{column})#{attr_type_cast}"
if is_order_field
Arel::Nodes::SqlLiteral.new(column_expr)
else
Arel::Nodes::SqlLiteral.new(
"#{column_expr} AS #{adapter_class.quote_column_name(field)}",
)
end
else
super
end
end
sig { params(field: T.untyped).returns(T.untyped) }
def order_column(field)
field = field.dup
field.instance_variable_set(:"@_is_order_field", true)
ret = super(field)
field.instance_variable_set(:"@_is_order_field", nil)
ret
end
end,
)
end
@@ -173,17 +189,17 @@ module AttrJsonRecordAliases
# end
# end
sig do
params(
attr_name: Symbol,
type: T.any(Symbol, ActiveModel::Type::Value),
options: T.untyped,
).void
end
def attr_json_scoped(attr_name, type, **options)
T.unsafe(self).attr_json(attr_name, type, **options)
# json_attributes_scope(attr_name, type)
end
# sig do
# params(
# attr_name: Symbol,
# type: T.any(Symbol, ActiveModel::Type::Value),
# options: T.untyped,
# ).void
# end
# def attr_json_scoped(attr_name, type, **options)
# T.unsafe(self).attr_json(attr_name, type, **options)
# # json_attributes_scope(attr_name, type)
# end
end
mixes_in_class_methods(ClassMethods)

View File

@@ -13,14 +13,14 @@ class Domain::E621::User < ReduxApplicationRecord
class_name: "Domain::E621::Post",
through: :favs,
source: :post
attr_json_scoped :favs_are_hidden, :boolean
attr_json :favs_are_hidden, :boolean
# number of favorites that the user has, derived from scraped html
# on /posts/<post_id>/favorites?page=<n>
# Used to find users with a significant number of favorites
attr_json_scoped :num_other_favs_cached, :integer
attr_json_scoped :scanned_favs_status, :string
attr_json_scoped :scanned_favs_at, :datetime
attr_json :num_other_favs_cached, :integer
attr_json :scanned_favs_status, :string
attr_json :scanned_favs_at, :datetime
sig { returns(T.nilable(::String)) }
def url_name

View File

@@ -15,24 +15,71 @@ class Domain::Post < ReduxApplicationRecord
super
end
sig { abstract.returns(T.nilable(String)) }
def to_param
end
sig { void }
def self.has_single_file!
# single file association
has_one :file,
class_name: "::Domain::PostFile",
inverse_of: :post,
dependent: :destroy
end
# multiple files association
has_many :files,
class_name: "::Domain::PostFile",
inverse_of: :post,
dependent: :destroy
sig { params(klass: T.class_of(Domain::User)).void }
def self.has_single_creator!(klass)
# single creator association
has_one :primary_user_post_creation,
class_name: "::Domain::UserPostCreation",
inverse_of: :post,
dependent: :destroy
has_one :creator,
class_name: klass.name,
through: :primary_user_post_creation,
source: :user
end
has_many :user_post_creations,
class_name: "::Domain::UserPostCreation",
inverse_of: :post,
dependent: :destroy
sig { params(klass: T.class_of(Domain::User)).void }
def self.has_multiple_creators!(klass)
# multiple creators association
has_many :creators,
class_name: klass.name,
through: :user_post_creations,
source: :user
end
has_many :user_post_favs,
class_name: "::Domain::UserPostFav",
inverse_of: :post,
dependent: :destroy
has_many :faving_users, through: :user_post_favs, source: :user
sig { params(klass: T.class_of(Domain::User)).void }
def self.has_faving_users!(klass)
has_many :faving_users,
class_name: klass.name,
through: :user_post_favs,
source: :user
end
sig { abstract.returns(T.nilable(String)) }
def to_param
sig { params(group_assoc_name: Symbol).void }
def self.belongs_to_groups!(group_assoc_name: :groups)
has_many :post_group_joins,
class_name: "::Domain::PostGroupJoin",
inverse_of: :post,
dependent: :destroy
has_many group_assoc_name, through: :post_group_joins, source: :group
end
end

View File

@@ -7,41 +7,45 @@ class Domain::Post::E621Post < Domain::Post
attr_json :log_entry_id, :integer
end
attr_json_scoped :state, :string
attr_json_scoped :e621_id, :integer
attr_json :state, :string
attr_json :e621_id, :integer
# When was the post's /posts/<post_id>/favorites pages scanned?
# Used to identify users with a significant number of favorites, setting
# their `num_other_favs_cached` attribute
attr_json_scoped :scanned_post_favs_at, :datetime
attr_json_scoped :rating, :string
attr_json_scoped :tags_array, ActiveModel::Type::Value.new
attr_json_scoped :flags_array, :string, array: true
attr_json_scoped :pools_array, :string, array: true
attr_json_scoped :sources_array, :string, array: true
attr_json_scoped :artists_array, :string, array: true
attr_json :scanned_post_favs_at, :datetime
attr_json :rating, :string
attr_json :tags_array, ActiveModel::Type::Value.new
attr_json :flags_array, :string, array: true
attr_json :pools_array, :string, array: true
attr_json :sources_array, :string, array: true
attr_json :artists_array, :string, array: true
attr_json_scoped :e621_updated_at, :datetime
attr_json_scoped :parent_post_e621_id, :integer
attr_json_scoped :last_index_page_id, :integer
attr_json_scoped :caused_by_entry_id, :integer
attr_json_scoped :scan_log_entry_id, :integer
attr_json_scoped :index_page_ids, :integer, array: true
attr_json_scoped :prev_md5s, :string, array: true
attr_json_scoped :scan_error, :string
attr_json_scoped :file_error, FileError.to_type
attr_json_scoped :uploader_user_id, :integer
attr_json :e621_updated_at, :datetime
attr_json :parent_post_e621_id, :integer
attr_json :last_index_page_id, :integer
attr_json :caused_by_entry_id, :integer
attr_json :scan_log_entry_id, :integer
attr_json :index_page_ids, :integer, array: true
attr_json :prev_md5s, :string, array: true
attr_json :scan_error, :string
attr_json :file_error, FileError.to_type
attr_json :uploader_user_id, :integer
has_single_file!
has_faving_users! Domain::User::E621User
belongs_to_groups! group_assoc_name: :pools
belongs_to :parent_post,
class_name: "Domain::Post::E621Post",
foreign_key: :parent_post_e621_id,
primary_key: :e621_id,
optional: true
belongs_to :uploader_user,
class_name: "::Domain::User::E621User",
inverse_of: :uploaded_posts,
optional: true
has_one :file, class_name: "::Domain::PostFile", foreign_key: :post_id
belongs_to :last_index_page, class_name: "HttpLogEntry", optional: true
validates :state, inclusion: { in: %w[ok removed scan_error file_error] }

View File

@@ -2,21 +2,21 @@
class Domain::Post::FaPost < Domain::Post
include AttrJsonRecordAliases
attr_json_scoped :title, :string
attr_json_scoped :state, :string
attr_json_scoped :fa_id, :integer
attr_json_scoped :category, :string
attr_json_scoped :theme, :string
attr_json_scoped :species, :string
attr_json_scoped :gender, :string
attr_json_scoped :description, :string
attr_json_scoped :keywords, :string, array: true, default: []
attr_json_scoped :num_favorites, :integer
attr_json_scoped :num_comments, :integer
attr_json_scoped :num_views, :integer
attr_json_scoped :posted_at, :datetime
attr_json_scoped :scanned_at, :datetime
attr_json_scoped :scan_file_error, :string
attr_json :title, :string
attr_json :state, :string
attr_json :fa_id, :integer
attr_json :category, :string
attr_json :theme, :string
attr_json :species, :string
attr_json :gender, :string
attr_json :description, :string
attr_json :keywords, :string, array: true, default: []
attr_json :num_favorites, :integer
attr_json :num_comments, :integer
attr_json :num_views, :integer
attr_json :posted_at, :datetime
attr_json :scanned_at, :datetime
attr_json :scan_file_error, :string
attr_json :last_user_page_id, :integer
attr_json :last_submission_page_id, :integer
attr_json :first_browse_page_id, :integer
@@ -29,22 +29,11 @@ class Domain::Post::FaPost < Domain::Post
belongs_to :first_gallery_page, class_name: "::HttpLogEntry", optional: true
belongs_to :first_seen_entry, class_name: "::HttpLogEntry", optional: true
has_one :user_post_creation,
class_name: "::Domain::UserPostCreation",
inverse_of: :post,
dependent: :destroy
has_single_creator! Domain::User::FaUser
has_single_file!
has_faving_users! Domain::User::FaUser
has_one :creator,
through: :user_post_creation,
source: :user,
class_name: "::Domain::User::FaUser"
has_one :file,
class_name: "::Domain::PostFile",
inverse_of: :post,
dependent: :destroy
after_initialize { self.state ||= "ok" if self.new_record? }
after_initialize { self.state ||= "ok" }
validates :state, inclusion: { in: %w[ok removed scan_error file_error] }
validates :fa_id, presence: true

View File

@@ -0,0 +1,41 @@
# typed: strict
class Domain::Post::InkbunnyPost < Domain::Post
attr_json :ib_id, :integer
attr_json :state, :string
attr_json :rating, :string
attr_json :submission_type, :string
has_single_creator! Domain::User::InkbunnyUser
has_faving_users! Domain::User::InkbunnyUser
belongs_to_groups! group_assoc_name: :pools
validates :ib_id, presence: true
validates :state, presence: true, inclusion: { in: %w[ok error] }
validates :rating, presence: true, inclusion: { in: %w[general mature adult] }
validates :submission_type,
presence: true,
inclusion: {
in: %w[
unknown
picture_pinup
sketch
picture_series
comic
portfolio
flash_animation
flash_interactive
video_feature
video_animation
music_single
music_album
writing_document
character_sheet
photography
],
}
sig { override.returns(T.nilable(String)) }
def to_param
"ib/#{self.ib_id}" if self.ib_id.present?
end
end

View File

@@ -4,11 +4,11 @@ class Domain::PostFile < ReduxApplicationRecord
self.table_name = "domain_post_files"
belongs_to :post, class_name: "::Domain::Post", inverse_of: :files
belongs_to :log_entry, class_name: "::HttpLogEntry"
belongs_to :log_entry, class_name: "::HttpLogEntry", optional: true
attr_json_scoped :state, :string
attr_json_scoped :url_str, :string
attr_json_scoped :error, :string
attr_json :state, :string
attr_json :url_str, :string
attr_json :error_message, :string
validates :state, inclusion: { in: %w[ok error] }

View File

@@ -0,0 +1,13 @@
# typed: strict
class Domain::PostGroup < ReduxApplicationRecord
extend T::Helpers
include AttrJsonRecordAliases
self.table_name = "domain_post_groups"
abstract!
has_many :post_group_joins,
class_name: "::Domain::PostGroupJoin",
inverse_of: :group,
dependent: :destroy
has_many :posts, through: :post_group_joins, source: :post
end

View File

@@ -0,0 +1,5 @@
# typed: strict
class Domain::PostGroup::E621Pool < Domain::PostGroup
attr_json :e621_id, :integer
validates :e621_id, presence: true
end

View File

@@ -0,0 +1,5 @@
# typed: strict
class Domain::PostGroup::InkbunnyPool < Domain::PostGroup
attr_json :ib_id, :integer
validates :ib_id, presence: true
end

View File

@@ -0,0 +1,10 @@
# typed: strict
class Domain::PostGroupJoin < ReduxApplicationRecord
extend T::Helpers
include AttrJsonRecordAliases
self.table_name = "domain_post_group_joins"
abstract!
belongs_to :post, class_name: "::Domain::Post"
belongs_to :group, class_name: "::Domain::PostGroup"
end

View File

@@ -0,0 +1,5 @@
# typed: strict
class Domain::PostGroupJoin::E621PoolJoin < Domain::PostGroupJoin
attr_json :left_post_id, :integer
attr_json :right_post_id, :integer
end

View File

@@ -0,0 +1,15 @@
# typed: strict
class Domain::PostGroupJoin::InkbunnyPoolJoin < Domain::PostGroupJoin
attr_json :left_post_id, :integer
attr_json :right_post_id, :integer
belongs_to :left_post,
class_name: "Domain::Post::InkbunnyPost",
foreign_key: :left_post_id,
optional: true
belongs_to :right_post,
class_name: "Domain::Post::InkbunnyPost",
foreign_key: :right_post_id,
optional: true
end

View File

@@ -15,7 +15,11 @@ class Domain::User < ReduxApplicationRecord
super
end
attr_json_scoped :migrated_user_favs_at, :datetime
sig { abstract.returns(T.nilable(String)) }
def to_param
end
attr_json :migrated_user_favs_at, :datetime
has_many :user_post_creations,
class_name: "::Domain::UserPostCreation",
@@ -39,6 +43,7 @@ class Domain::User < ReduxApplicationRecord
inverse_of: :to,
dependent: :destroy
has_many :posts, through: :user_post_creations, source: :post
has_many :faved_posts, through: :user_post_favs, source: :post
has_many :following_users, through: :user_user_follows_to, source: :to
has_many :followed_by_users, through: :user_user_follows_from, source: :from

View File

@@ -1,11 +1,11 @@
# typed: strict
class Domain::User::E621User < Domain::User
attr_json_scoped :e621_id, :integer
attr_json_scoped :name, :string
attr_json_scoped :favs_are_hidden, :boolean
attr_json_scoped :num_other_favs_cached, :integer
attr_json_scoped :scanned_favs_status, :string
attr_json_scoped :scanned_favs_at, :datetime
attr_json :e621_id, :integer
attr_json :name, :string
attr_json :favs_are_hidden, :boolean
attr_json :num_other_favs_cached, :integer
attr_json :scanned_favs_status, :string
attr_json :scanned_favs_at, :datetime
has_many :uploaded_posts,
class_name: "::Domain::Post::E621Post",
@@ -19,4 +19,9 @@ class Domain::User::E621User < Domain::User
}
validates :e621_id, presence: true
validates :name, length: { minimum: 1 }, allow_nil: false
sig { override.returns(T.nilable(String)) }
def to_param
"e621/#{e621_id}" if e621_id.present?
end
end

View File

@@ -1,27 +1,27 @@
# typed: strict
class Domain::User::FaUser < Domain::User
has_many :posts,
class_name: "::Domain::Fa::Post",
through: :user_post_creations,
source: :post
attr_json_scoped :name, :string
attr_json_scoped :url_name, :string
attr_json_scoped :full_name, :string
attr_json_scoped :artist_type, :string
attr_json_scoped :mood, :string
attr_json_scoped :profile_html, :string
attr_json_scoped :num_pageviews, :integer
attr_json_scoped :num_submissions, :integer
attr_json_scoped :num_comments_recieved, :integer
attr_json_scoped :num_comments_given, :integer
attr_json_scoped :num_journals, :integer
attr_json_scoped :num_favorites, :integer
attr_json_scoped :scanned_gallery_at, :datetime
attr_json_scoped :scanned_page_at, :datetime
attr_json_scoped :registered_at, :datetime
attr_json_scoped :migrated_followed_users_at, :datetime
attr_json :name, :string
attr_json :url_name, :string
attr_json :full_name, :string
attr_json :artist_type, :string
attr_json :mood, :string
attr_json :profile_html, :string
attr_json :num_pageviews, :integer
attr_json :num_submissions, :integer
attr_json :num_comments_recieved, :integer
attr_json :num_comments_given, :integer
attr_json :num_journals, :integer
attr_json :num_favorites, :integer
attr_json :scanned_gallery_at, :datetime
attr_json :scanned_page_at, :datetime
attr_json :registered_at, :datetime
attr_json :migrated_followed_users_at, :datetime
validates :name, presence: true
validates :url_name, presence: true
sig { override.returns(T.nilable(String)) }
def to_param
"fa/#{url_name}" if url_name.present?
end
end

View File

@@ -0,0 +1,31 @@
# typed: strict
class Domain::User::InkbunnyUser < Domain::User
attr_json :ib_id, :integer
attr_json :name, :string
attr_json :state, :string
attr_json :scanned_gallery_at, :datetime
attr_json :deep_update_log_entry_id, :integer
attr_json :shallow_update_log_entry_id, :integer
has_many :posts,
class_name: "::Domain::Inkbunny::Post",
through: :user_post_creations,
source: :post
belongs_to :deep_update_log_entry,
class_name: "::HttpLogEntry",
optional: true
belongs_to :shallow_update_log_entry,
class_name: "::HttpLogEntry",
optional: true
validates :ib_id, presence: true
validates :name, presence: true
validates :state, presence: true, inclusion: { in: %w[ok error] }
sig { override.returns(T.nilable(String)) }
def to_param
"ib/#{name}" if name.present?
end
end

View File

@@ -4,10 +4,13 @@ class Domain::UserAvatar < ReduxApplicationRecord
self.table_name = "domain_user_avatars"
belongs_to :user, class_name: "::Domain::User", inverse_of: :avatar
attr_json :url, :string
attr_json :url_str, :string
attr_json :state, :string
attr_json :downloaded_at, :datetime
attr_json :error_message, :string
attr_json :log_entry_id, :integer
belongs_to :log_entry, class_name: "::HttpLogEntry", optional: true
validates :state, presence: true, inclusion: { in: %w[ok error] }
end

View File

@@ -0,0 +1,69 @@
# typed: strict
class CreateUnifiedPostGroupTables < ActiveRecord::Migration[7.2]
extend T::Sig
GROUP_JOIN_TYPES = %w[
Domain::PostGroupJoin::InkbunnyPoolJoin
Domain::PostGroupJoin::E621PoolJoin
]
GROUP_TYPES = %w[Domain::PostGroup::InkbunnyPool Domain::PostGroup::E621Pool]
sig { void }
def change
up_only { execute "SET DEFAULT_TABLESPACE = mirai" }
reversible do |dir|
dir.up do
execute "CREATE TYPE domain_post_group_type AS ENUM (#{GROUP_TYPES.map { |t| "'#{t}'" }.join(",")})"
end
dir.down { execute "DROP TYPE domain_post_group_type" }
end
reversible do |dir|
dir.up do
execute "CREATE TYPE domain_post_group_join_type AS ENUM (#{GROUP_JOIN_TYPES.map { |t| "'#{t}'" }.join(",")})"
end
dir.down { execute "DROP TYPE domain_post_group_join_type" }
end
# allow null for log_entry_id for files which have not yet been downloaded
up_only do
change_column :domain_post_files, :log_entry_id, :integer, null: true
end
# avatars is not polymorphic, so we can remove the type column
remove_column :domain_user_avatars, :type, :string, null: false
create_table :domain_post_groups do |t|
t.enum :type, null: false, enum_type: "domain_post_group_type"
t.jsonb :json_attributes, default: {}
t.timestamps
t.index :type
end
create_table :domain_post_group_joins, id: false do |t|
t.enum :type, null: false, enum_type: "domain_post_group_join_type"
t.references :post,
index: false,
null: false,
foreign_key: {
to_table: :domain_posts,
}
t.references :group,
index: false,
null: false,
foreign_key: {
to_table: :domain_post_groups,
}
t.jsonb :json_attributes, default: {}
t.timestamps
t.index %i[post_id group_id], unique: true
t.index %i[group_id post_id]
t.index :type
end
end
end

View File

@@ -93,6 +93,26 @@ CREATE EXTENSION IF NOT EXISTS vector WITH SCHEMA public;
COMMENT ON EXTENSION vector IS 'vector data type and ivfflat access method';
--
-- Name: domain_post_group_join_type; Type: TYPE; Schema: public; Owner: -
--
CREATE TYPE public.domain_post_group_join_type AS ENUM (
'Domain::PostGroupJoin::InkbunnyPoolJoin',
'Domain::PostGroupJoin::E621PoolJoin'
);
--
-- Name: domain_post_group_type; Type: TYPE; Schema: public; Owner: -
--
CREATE TYPE public.domain_post_group_type AS ENUM (
'Domain::PostGroup::InkbunnyPool',
'Domain::PostGroup::E621Pool'
);
--
-- Name: domain_post_type; Type: TYPE; Schema: public; Owner: -
--
@@ -2668,7 +2688,7 @@ SET default_tablespace = mirai;
CREATE TABLE public.domain_post_files (
id bigint NOT NULL,
post_id bigint NOT NULL,
log_entry_id bigint NOT NULL,
log_entry_id integer,
json_attributes jsonb DEFAULT '{}'::jsonb,
created_at timestamp(6) without time zone NOT NULL,
updated_at timestamp(6) without time zone NOT NULL
@@ -2694,6 +2714,52 @@ CREATE SEQUENCE public.domain_post_files_id_seq
ALTER SEQUENCE public.domain_post_files_id_seq OWNED BY public.domain_post_files.id;
--
-- Name: domain_post_group_joins; Type: TABLE; Schema: public; Owner: -; Tablespace: mirai
--
CREATE TABLE public.domain_post_group_joins (
type public.domain_post_group_join_type NOT NULL,
post_id bigint NOT NULL,
group_id bigint 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
);
--
-- Name: domain_post_groups; Type: TABLE; Schema: public; Owner: -; Tablespace: mirai
--
CREATE TABLE public.domain_post_groups (
id bigint NOT NULL,
type public.domain_post_group_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
);
--
-- Name: domain_post_groups_id_seq; Type: SEQUENCE; Schema: public; Owner: -
--
CREATE SEQUENCE public.domain_post_groups_id_seq
START WITH 1
INCREMENT BY 1
NO MINVALUE
NO MAXVALUE
CACHE 1;
--
-- Name: domain_post_groups_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: -
--
ALTER SEQUENCE public.domain_post_groups_id_seq OWNED BY public.domain_post_groups.id;
--
-- Name: domain_posts; Type: TABLE; Schema: public; Owner: -; Tablespace: mirai
--
@@ -2861,7 +2927,6 @@ ALTER SEQUENCE public.domain_twitter_users_id_seq OWNED BY public.domain_twitter
CREATE TABLE public.domain_user_avatars (
id bigint NOT NULL,
type character varying NOT NULL,
user_id bigint NOT NULL,
json_attributes jsonb DEFAULT '{}'::jsonb,
created_at timestamp(6) without time zone NOT NULL,
@@ -4396,6 +4461,13 @@ ALTER TABLE ONLY public.domain_inkbunny_users ALTER COLUMN id SET DEFAULT nextva
ALTER TABLE ONLY public.domain_post_files ALTER COLUMN id SET DEFAULT nextval('public.domain_post_files_id_seq'::regclass);
--
-- Name: domain_post_groups id; Type: DEFAULT; Schema: public; Owner: -
--
ALTER TABLE ONLY public.domain_post_groups ALTER COLUMN id SET DEFAULT nextval('public.domain_post_groups_id_seq'::regclass);
--
-- Name: domain_posts id; Type: DEFAULT; Schema: public; Owner: -
--
@@ -5160,6 +5232,14 @@ ALTER TABLE ONLY public.domain_post_files
ADD CONSTRAINT domain_post_files_pkey PRIMARY KEY (id);
--
-- Name: domain_post_groups domain_post_groups_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: mirai
--
ALTER TABLE ONLY public.domain_post_groups
ADD CONSTRAINT domain_post_groups_pkey PRIMARY KEY (id);
--
-- Name: domain_posts domain_posts_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: mirai
--
@@ -6687,6 +6767,34 @@ CREATE INDEX index_domain_post_files_on_log_entry_id ON public.domain_post_files
CREATE INDEX index_domain_post_files_on_post_id ON public.domain_post_files USING btree (post_id);
--
-- Name: index_domain_post_group_joins_on_group_id_and_post_id; Type: INDEX; Schema: public; Owner: -; Tablespace: mirai
--
CREATE INDEX index_domain_post_group_joins_on_group_id_and_post_id ON public.domain_post_group_joins USING btree (group_id, post_id);
--
-- Name: index_domain_post_group_joins_on_post_id_and_group_id; Type: INDEX; Schema: public; Owner: -; Tablespace: mirai
--
CREATE UNIQUE INDEX index_domain_post_group_joins_on_post_id_and_group_id ON public.domain_post_group_joins USING btree (post_id, group_id);
--
-- Name: index_domain_post_group_joins_on_type; Type: INDEX; Schema: public; Owner: -; Tablespace: mirai
--
CREATE INDEX index_domain_post_group_joins_on_type ON public.domain_post_group_joins USING btree (type);
--
-- Name: index_domain_post_groups_on_type; Type: INDEX; Schema: public; Owner: -; Tablespace: mirai
--
CREATE INDEX index_domain_post_groups_on_type ON public.domain_post_groups USING btree (type);
--
-- Name: index_domain_posts_on_type; Type: INDEX; Schema: public; Owner: -; Tablespace: mirai
--
@@ -6750,13 +6858,6 @@ CREATE UNIQUE INDEX index_domain_twitter_users_on_name ON public.domain_twitter_
CREATE UNIQUE INDEX index_domain_twitter_users_on_tw_id ON public.domain_twitter_users USING btree (tw_id);
--
-- Name: index_domain_user_avatars_on_type; Type: INDEX; Schema: public; Owner: -; Tablespace: mirai
--
CREATE INDEX index_domain_user_avatars_on_type ON public.domain_user_avatars USING btree (type);
--
-- Name: index_domain_user_avatars_on_user_id; Type: INDEX; Schema: public; Owner: -; Tablespace: mirai
--
@@ -8001,6 +8102,14 @@ ALTER TABLE ONLY public.domain_fa_follows
ADD CONSTRAINT fk_rails_175679b7a2 FOREIGN KEY (followed_id) REFERENCES public.domain_fa_users(id);
--
-- Name: domain_post_group_joins fk_rails_22154fb920; Type: FK CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY public.domain_post_group_joins
ADD CONSTRAINT fk_rails_22154fb920 FOREIGN KEY (post_id) REFERENCES public.domain_posts(id);
--
-- Name: domain_inkbunny_favs fk_rails_22732bb65a; Type: FK CONSTRAINT; Schema: public; Owner: -
--
@@ -8249,6 +8358,14 @@ ALTER TABLE ONLY public.domain_inkbunny_follows
ADD CONSTRAINT fk_rails_dffb743e89 FOREIGN KEY (followed_id) REFERENCES public.domain_inkbunny_users(id);
--
-- Name: domain_post_group_joins fk_rails_eddd0a9390; Type: FK CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY public.domain_post_group_joins
ADD CONSTRAINT fk_rails_eddd0a9390 FOREIGN KEY (group_id) REFERENCES public.domain_post_groups(id);
--
-- Name: domain_inkbunny_follows fk_rails_ee473fedf4; Type: FK CONSTRAINT; Schema: public; Owner: -
--
@@ -8296,6 +8413,7 @@ ALTER TABLE ONLY public.domain_twitter_tweets
SET search_path TO "$user", public;
INSERT INTO "schema_migrations" (version) VALUES
('20250205035529'),
('20250203235035'),
('20250131060105'),
('20250131055824'),

View File

@@ -553,18 +553,6 @@ class Domain::E621::User
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def order(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def order_favs_are_hidden(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def order_num_other_favs_cached(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def order_scanned_favs_at(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def order_scanned_favs_status(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def preload(*args, &blk); end
@@ -608,18 +596,6 @@ class Domain::E621::User
sig { params(args: T.untyped).returns(PrivateAssociationRelation) }
def where(*args); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def where_favs_are_hidden(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def where_num_other_favs_cached(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def where_scanned_favs_at(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def where_scanned_favs_status(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def with(*args, &blk); end
@@ -1386,18 +1362,6 @@ class Domain::E621::User
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def order(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def order_favs_are_hidden(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def order_num_other_favs_cached(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def order_scanned_favs_at(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def order_scanned_favs_status(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def preload(*args, &blk); end
@@ -1441,18 +1405,6 @@ class Domain::E621::User
sig { params(args: T.untyped).returns(PrivateRelation) }
def where(*args); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def where_favs_are_hidden(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def where_num_other_favs_cached(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def where_scanned_favs_at(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def where_scanned_favs_status(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def with(*args, &blk); end

View File

@@ -411,20 +411,6 @@ class Domain::Post
end
module GeneratedAssociationMethods
sig { returns(T::Array[T.untyped]) }
def faving_user_ids; end
sig { params(ids: T::Array[T.untyped]).returns(T::Array[T.untyped]) }
def faving_user_ids=(ids); end
# This method is created by ActiveRecord on the `Domain::Post` class because it declared `has_many :faving_users, through: :user_post_favs`.
# 🔗 [Rails guide for `has_many_through` association](https://guides.rubyonrails.org/association_basics.html#the-has-many-through-association)
sig { returns(::Domain::User::PrivateCollectionProxy) }
def faving_users; end
sig { params(value: T::Enumerable[::Domain::User]).void }
def faving_users=(value); end
sig { returns(T::Array[T.untyped]) }
def file_ids; end

View File

@@ -488,12 +488,12 @@ class Domain::Post::E621Post
sig { params(ids: T::Array[T.untyped]).returns(T::Array[T.untyped]) }
def faving_user_ids=(ids); end
# This method is created by ActiveRecord on the `Domain::Post` class because it declared `has_many :faving_users, through: :user_post_favs`.
# This method is created by ActiveRecord on the `Domain::Post::E621Post` class because it declared `has_many :faving_users, through: :user_post_favs`.
# 🔗 [Rails guide for `has_many_through` association](https://guides.rubyonrails.org/association_basics.html#the-has-many-through-association)
sig { returns(::Domain::User::PrivateCollectionProxy) }
sig { returns(::Domain::User::E621User::PrivateCollectionProxy) }
def faving_users; end
sig { params(value: T::Enumerable[::Domain::User]).void }
sig { params(value: T::Enumerable[::Domain::User::E621User]).void }
def faving_users=(value); end
sig { returns(T.nilable(::Domain::PostFile)) }
@@ -540,6 +540,34 @@ class Domain::Post::E621Post
sig { returns(T::Boolean) }
def parent_post_previously_changed?; end
sig { returns(T::Array[T.untyped]) }
def pool_ids; end
sig { params(ids: T::Array[T.untyped]).returns(T::Array[T.untyped]) }
def pool_ids=(ids); end
# This method is created by ActiveRecord on the `Domain::Post::E621Post` class because it declared `has_many :pools, through: :post_group_joins`.
# 🔗 [Rails guide for `has_many_through` association](https://guides.rubyonrails.org/association_basics.html#the-has-many-through-association)
sig { returns(::Domain::PostGroup::PrivateCollectionProxy) }
def pools; end
sig { params(value: T::Enumerable[::Domain::PostGroup]).void }
def pools=(value); end
sig { returns(T::Array[T.untyped]) }
def post_group_join_ids; end
sig { params(ids: T::Array[T.untyped]).returns(T::Array[T.untyped]) }
def post_group_join_ids=(ids); end
# This method is created by ActiveRecord on the `Domain::Post::E621Post` class because it declared `has_many :post_group_joins`.
# 🔗 [Rails guide for `has_many` association](https://guides.rubyonrails.org/association_basics.html#the-has-many-association)
sig { returns(::Domain::PostGroupJoin::PrivateCollectionProxy) }
def post_group_joins; end
sig { params(value: T::Enumerable[::Domain::PostGroupJoin]).void }
def post_group_joins=(value); end
sig { returns(T.nilable(::Domain::PostFile)) }
def reload_file; end
@@ -696,63 +724,6 @@ class Domain::Post::E621Post
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def order(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def order_artists_array(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def order_caused_by_entry_id(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def order_e621_id(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def order_e621_updated_at(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def order_file_error(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def order_flags_array(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def order_index_page_ids(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def order_last_index_page_id(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def order_parent_post_e621_id(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def order_pools_array(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def order_prev_md5s(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def order_rating(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def order_scan_error(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def order_scan_log_entry_id(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def order_scanned_post_favs_at(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def order_sources_array(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def order_state(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def order_tags_array(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def order_uploader_user_id(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def preload(*args, &blk); end
@@ -796,63 +767,6 @@ class Domain::Post::E621Post
sig { params(args: T.untyped).returns(PrivateAssociationRelation) }
def where(*args); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def where_artists_array(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def where_caused_by_entry_id(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def where_e621_id(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def where_e621_updated_at(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def where_file_error(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def where_flags_array(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def where_index_page_ids(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def where_last_index_page_id(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def where_parent_post_e621_id(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def where_pools_array(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def where_prev_md5s(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def where_rating(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def where_scan_error(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def where_scan_log_entry_id(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def where_scanned_post_favs_at(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def where_sources_array(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def where_state(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def where_tags_array(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def where_uploader_user_id(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def with(*args, &blk); end
@@ -2421,63 +2335,6 @@ class Domain::Post::E621Post
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def order(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def order_artists_array(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def order_caused_by_entry_id(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def order_e621_id(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def order_e621_updated_at(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def order_file_error(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def order_flags_array(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def order_index_page_ids(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def order_last_index_page_id(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def order_parent_post_e621_id(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def order_pools_array(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def order_prev_md5s(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def order_rating(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def order_scan_error(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def order_scan_log_entry_id(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def order_scanned_post_favs_at(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def order_sources_array(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def order_state(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def order_tags_array(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def order_uploader_user_id(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def preload(*args, &blk); end
@@ -2521,63 +2378,6 @@ class Domain::Post::E621Post
sig { params(args: T.untyped).returns(PrivateRelation) }
def where(*args); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def where_artists_array(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def where_caused_by_entry_id(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def where_e621_id(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def where_e621_updated_at(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def where_file_error(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def where_flags_array(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def where_index_page_ids(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def where_last_index_page_id(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def where_parent_post_e621_id(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def where_pools_array(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def where_prev_md5s(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def where_rating(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def where_scan_error(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def where_scan_log_entry_id(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def where_scanned_post_favs_at(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def where_sources_array(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def where_state(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def where_tags_array(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def where_uploader_user_id(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def with(*args, &blk); end

View File

@@ -465,7 +465,7 @@ class Domain::Post::FaPost
def build_last_user_page(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(::Domain::UserPostCreation) }
def build_user_post_creation(*args, &blk); end
def build_primary_user_post_creation(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(::Domain::User::FaUser) }
def create_creator(*args, &blk); end
@@ -510,10 +510,10 @@ class Domain::Post::FaPost
def create_last_user_page!(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(::Domain::UserPostCreation) }
def create_user_post_creation(*args, &blk); end
def create_primary_user_post_creation(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(::Domain::UserPostCreation) }
def create_user_post_creation!(*args, &blk); end
def create_primary_user_post_creation!(*args, &blk); end
sig { returns(T.nilable(::Domain::User::FaUser)) }
def creator; end
@@ -527,12 +527,12 @@ class Domain::Post::FaPost
sig { params(ids: T::Array[T.untyped]).returns(T::Array[T.untyped]) }
def faving_user_ids=(ids); end
# This method is created by ActiveRecord on the `Domain::Post` class because it declared `has_many :faving_users, through: :user_post_favs`.
# This method is created by ActiveRecord on the `Domain::Post::FaPost` class because it declared `has_many :faving_users, through: :user_post_favs`.
# 🔗 [Rails guide for `has_many_through` association](https://guides.rubyonrails.org/association_basics.html#the-has-many-through-association)
sig { returns(::Domain::User::PrivateCollectionProxy) }
sig { returns(::Domain::User::FaUser::PrivateCollectionProxy) }
def faving_users; end
sig { params(value: T::Enumerable[::Domain::User]).void }
sig { params(value: T::Enumerable[::Domain::User::FaUser]).void }
def faving_users=(value); end
sig { returns(T.nilable(::Domain::PostFile)) }
@@ -615,6 +615,12 @@ class Domain::Post::FaPost
sig { returns(T::Boolean) }
def last_user_page_previously_changed?; end
sig { returns(T.nilable(::Domain::UserPostCreation)) }
def primary_user_post_creation; end
sig { params(value: T.nilable(::Domain::UserPostCreation)).void }
def primary_user_post_creation=(value); end
sig { returns(T.nilable(::Domain::User::FaUser)) }
def reload_creator; end
@@ -637,7 +643,7 @@ class Domain::Post::FaPost
def reload_last_user_page; end
sig { returns(T.nilable(::Domain::UserPostCreation)) }
def reload_user_post_creation; end
def reload_primary_user_post_creation; end
sig { void }
def reset_creator; end
@@ -661,13 +667,7 @@ class Domain::Post::FaPost
def reset_last_user_page; end
sig { void }
def reset_user_post_creation; end
sig { returns(T.nilable(::Domain::UserPostCreation)) }
def user_post_creation; end
sig { params(value: T.nilable(::Domain::UserPostCreation)).void }
def user_post_creation=(value); end
def reset_primary_user_post_creation; end
sig { returns(T::Array[T.untyped]) }
def user_post_creation_ids; end
@@ -789,51 +789,6 @@ class Domain::Post::FaPost
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def order(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def order_category(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def order_description(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def order_fa_id(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def order_gender(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def order_keywords(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def order_num_comments(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def order_num_favorites(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def order_num_views(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def order_posted_at(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def order_scan_file_error(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def order_scanned_at(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def order_species(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def order_state(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def order_theme(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def order_title(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def preload(*args, &blk); end
@@ -877,51 +832,6 @@ class Domain::Post::FaPost
sig { params(args: T.untyped).returns(PrivateAssociationRelation) }
def where(*args); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def where_category(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def where_description(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def where_fa_id(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def where_gender(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def where_keywords(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def where_num_comments(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def where_num_favorites(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def where_num_views(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def where_posted_at(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def where_scan_file_error(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def where_scanned_at(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def where_species(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def where_state(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def where_theme(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def where_title(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def with(*args, &blk); end
@@ -2547,51 +2457,6 @@ class Domain::Post::FaPost
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def order(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def order_category(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def order_description(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def order_fa_id(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def order_gender(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def order_keywords(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def order_num_comments(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def order_num_favorites(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def order_num_views(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def order_posted_at(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def order_scan_file_error(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def order_scanned_at(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def order_species(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def order_state(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def order_theme(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def order_title(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def preload(*args, &blk); end
@@ -2635,51 +2500,6 @@ class Domain::Post::FaPost
sig { params(args: T.untyped).returns(PrivateRelation) }
def where(*args); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def where_category(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def where_description(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def where_fa_id(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def where_gender(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def where_keywords(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def where_num_comments(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def where_num_favorites(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def where_num_views(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def where_posted_at(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def where_scan_file_error(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def where_scanned_at(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def where_species(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def where_state(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def where_theme(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def where_title(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def with(*args, &blk); end

File diff suppressed because it is too large Load Diff

View File

@@ -557,15 +557,6 @@ class Domain::PostFile
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def order(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def order_error(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def order_state(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def order_url_str(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def preload(*args, &blk); end
@@ -609,15 +600,6 @@ class Domain::PostFile
sig { params(args: T.untyped).returns(PrivateAssociationRelation) }
def where(*args); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def where_error(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def where_state(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def where_url_str(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def with(*args, &blk); end
@@ -685,49 +667,49 @@ class Domain::PostFile
def created_at_will_change!; end
sig { returns(T.nilable(::String)) }
def error; end
def error_message; end
sig { params(value: T.nilable(::String)).returns(T.nilable(::String)) }
def error=(value); end
def error_message=(value); end
sig { returns(T::Boolean) }
def error?; end
def error_message?; end
sig { returns(T.nilable(::String)) }
def error_before_last_save; end
def error_message_before_last_save; end
sig { returns(T.untyped) }
def error_before_type_cast; end
def error_message_before_type_cast; end
sig { returns(T::Boolean) }
def error_came_from_user?; end
def error_message_came_from_user?; end
sig { returns(T.nilable([T.nilable(::String), T.nilable(::String)])) }
def error_change; end
def error_message_change; end
sig { returns(T.nilable([T.nilable(::String), T.nilable(::String)])) }
def error_change_to_be_saved; end
def error_message_change_to_be_saved; end
sig { params(from: T.nilable(::String), to: T.nilable(::String)).returns(T::Boolean) }
def error_changed?(from: T.unsafe(nil), to: T.unsafe(nil)); end
def error_message_changed?(from: T.unsafe(nil), to: T.unsafe(nil)); end
sig { returns(T.nilable(::String)) }
def error_in_database; end
def error_message_in_database; end
sig { returns(T.nilable([T.nilable(::String), T.nilable(::String)])) }
def error_previous_change; end
def error_message_previous_change; end
sig { params(from: T.nilable(::String), to: T.nilable(::String)).returns(T::Boolean) }
def error_previously_changed?(from: T.unsafe(nil), to: T.unsafe(nil)); end
def error_message_previously_changed?(from: T.unsafe(nil), to: T.unsafe(nil)); end
sig { returns(T.nilable(::String)) }
def error_previously_was; end
def error_message_previously_was; end
sig { returns(T.nilable(::String)) }
def error_was; end
def error_message_was; end
sig { void }
def error_will_change!; end
def error_message_will_change!; end
sig { returns(T.nilable(::Integer)) }
def id; end
@@ -958,7 +940,7 @@ class Domain::PostFile
def restore_created_at!; end
sig { void }
def restore_error!; end
def restore_error_message!; end
sig { void }
def restore_id!; end
@@ -991,10 +973,10 @@ class Domain::PostFile
def saved_change_to_created_at?; end
sig { returns(T.nilable([T.nilable(::String), T.nilable(::String)])) }
def saved_change_to_error; end
def saved_change_to_error_message; end
sig { returns(T::Boolean) }
def saved_change_to_error?; end
def saved_change_to_error_message?; end
sig { returns(T.nilable([T.nilable(::Integer), T.nilable(::Integer)])) }
def saved_change_to_id; end
@@ -1193,7 +1175,7 @@ class Domain::PostFile
def will_save_change_to_created_at?; end
sig { returns(T::Boolean) }
def will_save_change_to_error?; end
def will_save_change_to_error_message?; end
sig { returns(T::Boolean) }
def will_save_change_to_id?; end
@@ -1311,15 +1293,6 @@ class Domain::PostFile
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def order(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def order_error(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def order_state(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def order_url_str(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def preload(*args, &blk); end
@@ -1363,15 +1336,6 @@ class Domain::PostFile
sig { params(args: T.untyped).returns(PrivateRelation) }
def where(*args); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def where_error(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def where_state(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def where_url_str(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def with(*args, &blk); end

1283
sorbet/rbi/dsl/domain/post_group.rbi generated Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

1398
sorbet/rbi/dsl/domain/post_group_join.rbi generated Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -482,6 +482,20 @@ class Domain::User
sig { params(value: T::Enumerable[::Domain::User]).void }
def following_users=(value); end
sig { returns(T::Array[T.untyped]) }
def post_ids; end
sig { params(ids: T::Array[T.untyped]).returns(T::Array[T.untyped]) }
def post_ids=(ids); end
# This method is created by ActiveRecord on the `Domain::User` class because it declared `has_many :posts, through: :user_post_creations`.
# 🔗 [Rails guide for `has_many_through` association](https://guides.rubyonrails.org/association_basics.html#the-has-many-through-association)
sig { returns(::Domain::Post::PrivateCollectionProxy) }
def posts; end
sig { params(value: T::Enumerable[::Domain::Post]).void }
def posts=(value); end
sig { returns(T.nilable(::Domain::UserAvatar)) }
def reload_avatar; end
@@ -636,9 +650,6 @@ class Domain::User
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def order(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def order_migrated_user_favs_at(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def preload(*args, &blk); end
@@ -682,9 +693,6 @@ class Domain::User
sig { params(args: T.untyped).returns(PrivateAssociationRelation) }
def where(*args); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def where_migrated_user_favs_at(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def with(*args, &blk); end
@@ -1217,9 +1225,6 @@ class Domain::User
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def order(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def order_migrated_user_favs_at(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def preload(*args, &blk); end
@@ -1263,9 +1268,6 @@ class Domain::User
sig { params(args: T.untyped).returns(PrivateRelation) }
def where(*args); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def where_migrated_user_favs_at(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def with(*args, &blk); end

View File

@@ -514,6 +514,20 @@ class Domain::User::E621User
sig { params(value: T::Enumerable[::Domain::User]).void }
def following_users=(value); end
sig { returns(T::Array[T.untyped]) }
def post_ids; end
sig { params(ids: T::Array[T.untyped]).returns(T::Array[T.untyped]) }
def post_ids=(ids); end
# This method is created by ActiveRecord on the `Domain::User` class because it declared `has_many :posts, through: :user_post_creations`.
# 🔗 [Rails guide for `has_many_through` association](https://guides.rubyonrails.org/association_basics.html#the-has-many-through-association)
sig { returns(::Domain::Post::PrivateCollectionProxy) }
def posts; end
sig { params(value: T::Enumerable[::Domain::Post]).void }
def posts=(value); end
sig { returns(T.nilable(::Domain::UserAvatar)) }
def reload_avatar; end
@@ -682,27 +696,6 @@ class Domain::User::E621User
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def order(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def order_e621_id(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def order_favs_are_hidden(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def order_migrated_user_favs_at(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def order_name(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def order_num_other_favs_cached(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def order_scanned_favs_at(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def order_scanned_favs_status(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def preload(*args, &blk); end
@@ -746,27 +739,6 @@ class Domain::User::E621User
sig { params(args: T.untyped).returns(PrivateAssociationRelation) }
def where(*args); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def where_e621_id(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def where_favs_are_hidden(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def where_migrated_user_favs_at(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def where_name(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def where_num_other_favs_cached(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def where_scanned_favs_at(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def where_scanned_favs_status(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def with(*args, &blk); end
@@ -1651,27 +1623,6 @@ class Domain::User::E621User
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def order(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def order_e621_id(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def order_favs_are_hidden(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def order_migrated_user_favs_at(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def order_name(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def order_num_other_favs_cached(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def order_scanned_favs_at(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def order_scanned_favs_status(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def preload(*args, &blk); end
@@ -1715,27 +1666,6 @@ class Domain::User::E621User
sig { params(args: T.untyped).returns(PrivateRelation) }
def where(*args); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def where_e621_id(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def where_favs_are_hidden(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def where_migrated_user_favs_at(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def where_name(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def where_num_other_favs_cached(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def where_scanned_favs_at(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def where_scanned_favs_status(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def with(*args, &blk); end

View File

@@ -520,12 +520,12 @@ class Domain::User::FaUser
sig { params(ids: T::Array[T.untyped]).returns(T::Array[T.untyped]) }
def post_ids=(ids); end
# This method is created by ActiveRecord on the `Domain::User::FaUser` class because it declared `has_many :posts, through: :user_post_creations`.
# This method is created by ActiveRecord on the `Domain::User` class because it declared `has_many :posts, through: :user_post_creations`.
# 🔗 [Rails guide for `has_many_through` association](https://guides.rubyonrails.org/association_basics.html#the-has-many-through-association)
sig { returns(::Domain::Fa::Post::PrivateCollectionProxy) }
sig { returns(::Domain::Post::PrivateCollectionProxy) }
def posts; end
sig { params(value: T::Enumerable[::Domain::Fa::Post]).void }
sig { params(value: T::Enumerable[::Domain::Post]).void }
def posts=(value); end
sig { returns(T.nilable(::Domain::UserAvatar)) }
@@ -682,57 +682,6 @@ class Domain::User::FaUser
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def order(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def order_artist_type(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def order_full_name(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def order_migrated_followed_users_at(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def order_migrated_user_favs_at(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def order_mood(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def order_name(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def order_num_comments_given(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def order_num_comments_recieved(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def order_num_favorites(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def order_num_journals(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def order_num_pageviews(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def order_num_submissions(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def order_profile_html(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def order_registered_at(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def order_scanned_gallery_at(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def order_scanned_page_at(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def order_url_name(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def preload(*args, &blk); end
@@ -776,57 +725,6 @@ class Domain::User::FaUser
sig { params(args: T.untyped).returns(PrivateAssociationRelation) }
def where(*args); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def where_artist_type(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def where_full_name(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def where_migrated_followed_users_at(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def where_migrated_user_favs_at(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def where_mood(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def where_name(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def where_num_comments_given(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def where_num_comments_recieved(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def where_num_favorites(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def where_num_journals(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def where_num_pageviews(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def where_num_submissions(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def where_profile_html(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def where_registered_at(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def where_scanned_gallery_at(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def where_scanned_page_at(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def where_url_name(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def with(*args, &blk); end
@@ -2311,57 +2209,6 @@ class Domain::User::FaUser
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def order(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def order_artist_type(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def order_full_name(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def order_migrated_followed_users_at(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def order_migrated_user_favs_at(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def order_mood(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def order_name(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def order_num_comments_given(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def order_num_comments_recieved(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def order_num_favorites(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def order_num_journals(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def order_num_pageviews(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def order_num_submissions(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def order_profile_html(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def order_registered_at(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def order_scanned_gallery_at(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def order_scanned_page_at(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def order_url_name(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def preload(*args, &blk); end
@@ -2405,57 +2252,6 @@ class Domain::User::FaUser
sig { params(args: T.untyped).returns(PrivateRelation) }
def where(*args); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def where_artist_type(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def where_full_name(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def where_migrated_followed_users_at(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def where_migrated_user_favs_at(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def where_mood(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def where_name(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def where_num_comments_given(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def where_num_comments_recieved(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def where_num_favorites(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def where_num_journals(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def where_num_pageviews(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def where_num_submissions(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def where_profile_html(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def where_registered_at(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def where_scanned_gallery_at(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def where_scanned_page_at(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def where_url_name(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def with(*args, &blk); end

File diff suppressed because it is too large Load Diff

View File

@@ -737,6 +737,51 @@ class Domain::UserAvatar
sig { void }
def downloaded_at_will_change!; end
sig { returns(T.nilable(::String)) }
def error_message; end
sig { params(value: T.nilable(::String)).returns(T.nilable(::String)) }
def error_message=(value); end
sig { returns(T::Boolean) }
def error_message?; end
sig { returns(T.nilable(::String)) }
def error_message_before_last_save; end
sig { returns(T.untyped) }
def error_message_before_type_cast; end
sig { returns(T::Boolean) }
def error_message_came_from_user?; end
sig { returns(T.nilable([T.nilable(::String), T.nilable(::String)])) }
def error_message_change; end
sig { returns(T.nilable([T.nilable(::String), T.nilable(::String)])) }
def error_message_change_to_be_saved; end
sig { params(from: T.nilable(::String), to: T.nilable(::String)).returns(T::Boolean) }
def error_message_changed?(from: T.unsafe(nil), to: T.unsafe(nil)); end
sig { returns(T.nilable(::String)) }
def error_message_in_database; end
sig { returns(T.nilable([T.nilable(::String), T.nilable(::String)])) }
def error_message_previous_change; end
sig { params(from: T.nilable(::String), to: T.nilable(::String)).returns(T::Boolean) }
def error_message_previously_changed?(from: T.unsafe(nil), to: T.unsafe(nil)); end
sig { returns(T.nilable(::String)) }
def error_message_previously_was; end
sig { returns(T.nilable(::String)) }
def error_message_was; end
sig { void }
def error_message_will_change!; end
sig { returns(T.nilable(::Integer)) }
def id; end
@@ -923,6 +968,9 @@ class Domain::UserAvatar
sig { void }
def restore_downloaded_at!; end
sig { void }
def restore_error_message!; end
sig { void }
def restore_id!; end
@@ -938,14 +986,11 @@ class Domain::UserAvatar
sig { void }
def restore_state!; end
sig { void }
def restore_type!; end
sig { void }
def restore_updated_at!; end
sig { void }
def restore_url!; end
def restore_url_str!; end
sig { void }
def restore_user_id!; end
@@ -962,6 +1007,12 @@ class Domain::UserAvatar
sig { returns(T::Boolean) }
def saved_change_to_downloaded_at?; end
sig { returns(T.nilable([T.nilable(::String), T.nilable(::String)])) }
def saved_change_to_error_message; end
sig { returns(T::Boolean) }
def saved_change_to_error_message?; end
sig { returns(T.nilable([T.nilable(::Integer), T.nilable(::Integer)])) }
def saved_change_to_id; end
@@ -992,12 +1043,6 @@ class Domain::UserAvatar
sig { returns(T::Boolean) }
def saved_change_to_state?; end
sig { returns(T.nilable([T.nilable(::String), T.nilable(::String)])) }
def saved_change_to_type; end
sig { returns(T::Boolean) }
def saved_change_to_type?; end
sig { returns(T.nilable([T.nilable(::ActiveSupport::TimeWithZone), T.nilable(::ActiveSupport::TimeWithZone)])) }
def saved_change_to_updated_at; end
@@ -1005,10 +1050,10 @@ class Domain::UserAvatar
def saved_change_to_updated_at?; end
sig { returns(T.nilable([T.nilable(::String), T.nilable(::String)])) }
def saved_change_to_url; end
def saved_change_to_url_str; end
sig { returns(T::Boolean) }
def saved_change_to_url?; end
def saved_change_to_url_str?; end
sig { returns(T.nilable([T.nilable(::Integer), T.nilable(::Integer)])) }
def saved_change_to_user_id; end
@@ -1061,51 +1106,6 @@ class Domain::UserAvatar
sig { void }
def state_will_change!; end
sig { returns(T.nilable(::String)) }
def type; end
sig { params(value: T.nilable(::String)).returns(T.nilable(::String)) }
def type=(value); end
sig { returns(T::Boolean) }
def type?; end
sig { returns(T.nilable(::String)) }
def type_before_last_save; end
sig { returns(T.untyped) }
def type_before_type_cast; end
sig { returns(T::Boolean) }
def type_came_from_user?; end
sig { returns(T.nilable([T.nilable(::String), T.nilable(::String)])) }
def type_change; end
sig { returns(T.nilable([T.nilable(::String), T.nilable(::String)])) }
def type_change_to_be_saved; end
sig { params(from: T.nilable(::String), to: T.nilable(::String)).returns(T::Boolean) }
def type_changed?(from: T.unsafe(nil), to: T.unsafe(nil)); end
sig { returns(T.nilable(::String)) }
def type_in_database; end
sig { returns(T.nilable([T.nilable(::String), T.nilable(::String)])) }
def type_previous_change; end
sig { params(from: T.nilable(::String), to: T.nilable(::String)).returns(T::Boolean) }
def type_previously_changed?(from: T.unsafe(nil), to: T.unsafe(nil)); end
sig { returns(T.nilable(::String)) }
def type_previously_was; end
sig { returns(T.nilable(::String)) }
def type_was; end
sig { void }
def type_will_change!; end
sig { returns(T.nilable(::ActiveSupport::TimeWithZone)) }
def updated_at; end
@@ -1162,49 +1162,49 @@ class Domain::UserAvatar
def updated_at_will_change!; end
sig { returns(T.nilable(::String)) }
def url; end
def url_str; end
sig { params(value: T.nilable(::String)).returns(T.nilable(::String)) }
def url=(value); end
def url_str=(value); end
sig { returns(T::Boolean) }
def url?; end
def url_str?; end
sig { returns(T.nilable(::String)) }
def url_before_last_save; end
def url_str_before_last_save; end
sig { returns(T.untyped) }
def url_before_type_cast; end
def url_str_before_type_cast; end
sig { returns(T::Boolean) }
def url_came_from_user?; end
def url_str_came_from_user?; end
sig { returns(T.nilable([T.nilable(::String), T.nilable(::String)])) }
def url_change; end
def url_str_change; end
sig { returns(T.nilable([T.nilable(::String), T.nilable(::String)])) }
def url_change_to_be_saved; end
def url_str_change_to_be_saved; end
sig { params(from: T.nilable(::String), to: T.nilable(::String)).returns(T::Boolean) }
def url_changed?(from: T.unsafe(nil), to: T.unsafe(nil)); end
def url_str_changed?(from: T.unsafe(nil), to: T.unsafe(nil)); end
sig { returns(T.nilable(::String)) }
def url_in_database; end
def url_str_in_database; end
sig { returns(T.nilable([T.nilable(::String), T.nilable(::String)])) }
def url_previous_change; end
def url_str_previous_change; end
sig { params(from: T.nilable(::String), to: T.nilable(::String)).returns(T::Boolean) }
def url_previously_changed?(from: T.unsafe(nil), to: T.unsafe(nil)); end
def url_str_previously_changed?(from: T.unsafe(nil), to: T.unsafe(nil)); end
sig { returns(T.nilable(::String)) }
def url_previously_was; end
def url_str_previously_was; end
sig { returns(T.nilable(::String)) }
def url_was; end
def url_str_was; end
sig { void }
def url_will_change!; end
def url_str_will_change!; end
sig { returns(T.nilable(::Integer)) }
def user_id; end
@@ -1257,6 +1257,9 @@ class Domain::UserAvatar
sig { returns(T::Boolean) }
def will_save_change_to_downloaded_at?; end
sig { returns(T::Boolean) }
def will_save_change_to_error_message?; end
sig { returns(T::Boolean) }
def will_save_change_to_id?; end
@@ -1272,14 +1275,11 @@ class Domain::UserAvatar
sig { returns(T::Boolean) }
def will_save_change_to_state?; end
sig { returns(T::Boolean) }
def will_save_change_to_type?; end
sig { returns(T::Boolean) }
def will_save_change_to_updated_at?; end
sig { returns(T::Boolean) }
def will_save_change_to_url?; end
def will_save_change_to_url_str?; end
sig { returns(T::Boolean) }
def will_save_change_to_user_id?; end

View File

@@ -1,10 +1,11 @@
# typed: false
FactoryBot.define do
factory :http_log_entry do
sequence(:uri_host) { |n| "example#{n}.com" }
uri_scheme { "https" }
uri_path { "/path" }
uri_query { nil }
transient { uri_str { "https://example.com/path" } }
uri_host { URI.parse(uri_str).host }
uri_scheme { URI.parse(uri_str).scheme }
uri_path { URI.parse(uri_str).path }
uri_query { URI.parse(uri_str).query }
verb { :get }
status_code { 200 }
content_type { "text/html" }

View File

@@ -2,7 +2,8 @@
require "rails_helper"
RSpec.describe Domain::MigrateToDomain do
let(:migrator) { described_class.new }
# sink to /dev/null
let(:migrator) { described_class.new(File.open("/dev/null", "w")) }
def expect_users_match(old_user, new_user)
expect(new_user).to have_attributes(
@@ -103,6 +104,91 @@ RSpec.describe Domain::MigrateToDomain do
end
end
def expect_inkbunny_posts_match(old_post, new_post)
expect(new_post).to have_attributes(
state: old_post.state,
ib_id: old_post.ib_post_id,
rating: old_post.rating,
submission_type: old_post.submission_type,
created_at: be_within(1.second).of(old_post.created_at),
)
if old_post.creator.present?
expect(new_post.creator).to have_attributes(
ib_id: old_post.creator.ib_user_id,
)
else
expect(new_post.creator).to be_nil
end
if old_post.files.present?
expect(new_post.files.map(&:log_entry_id)).to match_array(
old_post.files.map(&:log_entry_id),
)
expect(new_post.files.map(&:url_str)).to match_array(
old_post.files.map(&:url_str),
)
expect(new_post.files.map(&:state)).to match_array(
old_post.files.map(&:state),
)
else
expect(new_post.files).to be_empty
end
end
def expect_inkbunny_users_match(old_user, new_user)
expect(new_user).to have_attributes(
ib_id: old_user.ib_user_id,
name: old_user.name,
state: old_user.state.to_s,
scanned_gallery_at:
be_within(1.second).of(old_user.scanned_gallery_at) || be_nil,
deep_update_log_entry_id: old_user.deep_update_log_entry_id,
shallow_update_log_entry_id: old_user.shallow_update_log_entry_id,
created_at: be_within(1.second).of(old_user.created_at),
)
if old_user.avatar_log_entry.present?
expect(new_user.avatar).to have_attributes(
log_entry_id: old_user.avatar_log_entry.id,
url_str: old_user.avatar_log_entry.uri_str,
state: old_user.avatar_log_entry.status_code == 200 ? "ok" : "error",
)
else
expect(new_user.avatar).to be_nil
end
end
def expect_inkbunny_pools_match(old_pool, new_pool)
expect(new_pool).to have_attributes(ib_id: old_pool.ib_pool_id)
if old_pool.pool_joins.present?
expect(new_pool.post_group_joins.count).to eq(old_pool.pool_joins.count)
old_pool.pool_joins.each_with_index do |old_join, i|
new_join = new_pool.post_group_joins[i]
expect(new_join.post.ib_id).to eq(old_join.post.ib_post_id)
if old_join.left_post.present?
expect(new_join.left_post.ib_id).to eq(old_join.left_post.ib_post_id)
else
expect(new_join.left_post).to be_nil
end
if old_join.right_post.present?
expect(new_join.right_post.ib_id).to eq(
old_join.right_post.ib_post_id,
)
else
expect(new_join.right_post).to be_nil
end
end
else
expect(new_pool.post_group_joins).to be_empty
end
end
describe "#migrate_e621_users" do
let!(:old_user) do
Domain::E621::User.create!(
@@ -506,4 +592,416 @@ RSpec.describe Domain::MigrateToDomain do
expect_fa_posts_match(post_without_file, new_post)
end
end
describe "#migrate_inkbunny_posts" do
let!(:creator) do
Domain::Inkbunny::User.create!(
name: "artist1",
ib_user_id: 123,
state: :ok,
state_detail: {
},
)
end
let!(:new_creator) do
Domain::User::InkbunnyUser.create!(
name: "artist1",
ib_id: 123,
state: "ok",
)
end
let!(:old_post) do
post = create(:domain_inkbunny_post, creator: creator)
file = create(:domain_inkbunny_file, post: post)
post.files << file
post
end
it "migrates posts that don't exist in the new table" do
expect { migrator.migrate_inkbunny_posts }.to change(
Domain::Post::InkbunnyPost,
:count,
).by(1)
new_post = Domain::Post::InkbunnyPost.find_by(ib_id: old_post.ib_post_id)
expect_inkbunny_posts_match(old_post, new_post)
end
it "skips posts that already exist in the new table" do
# Create a post in the new table first
Domain::Post::InkbunnyPost.create!(
ib_id: old_post.ib_post_id,
state: "ok",
rating: "general",
submission_type: "picture_pinup",
)
expect { migrator.migrate_inkbunny_posts }.not_to change(
Domain::Post::InkbunnyPost,
:count,
)
end
it "handles multiple posts in batches" do
# Create a few more old posts
additional_posts =
2.times.map do |i|
post = create(:domain_inkbunny_post, creator: creator)
file = create(:domain_inkbunny_file, post: post)
post.files << file
post
end
expect { migrator.migrate_inkbunny_posts }.to change(
Domain::Post::InkbunnyPost,
:count,
).by(3)
expect(Domain::Post::InkbunnyPost.count).to eq(3)
expect(Domain::Post::InkbunnyPost.pluck(:ib_id)).to contain_exactly(
old_post.ib_post_id,
additional_posts[0].ib_post_id,
additional_posts[1].ib_post_id,
)
# Verify all posts were migrated correctly
([old_post] + additional_posts).each do |old_post|
new_post =
Domain::Post::InkbunnyPost.find_by(ib_id: old_post.ib_post_id)
expect_inkbunny_posts_match(old_post, new_post)
end
end
it "handles posts without files" do
post_without_files =
Domain::Inkbunny::Post.create!(
ib_post_id: 999,
state: :ok,
state_detail: {
},
rating: :general,
submission_type: :picture_pinup,
creator: creator,
)
expect { migrator.migrate_inkbunny_posts }.to change(
Domain::Post::InkbunnyPost,
:count,
).by(2)
new_post =
Domain::Post::InkbunnyPost.find_by(ib_id: post_without_files.ib_post_id)
expect_inkbunny_posts_match(post_without_files, new_post)
end
end
describe "#migrate_inkbunny_users" do
let!(:old_user) do
create(
:domain_inkbunny_user,
name: "test_user",
ib_user_id: 123,
state: :ok,
state_detail: {
},
scanned_gallery_at: Time.current,
deep_update_log_entry: create(:http_log_entry),
shallow_update_log_entry: create(:http_log_entry),
)
end
it "migrates users that don't exist in the new table" do
expect { migrator.migrate_inkbunny_users }.to change(
Domain::User::InkbunnyUser,
:count,
).by(1)
new_user = Domain::User::InkbunnyUser.find_by(ib_id: old_user.ib_user_id)
expect_inkbunny_users_match(old_user, new_user)
end
it "skips users that already exist in the new table" do
# Create a user in the new table first
Domain::User::InkbunnyUser.create!(
ib_id: old_user.ib_user_id,
name: old_user.name,
state: "ok",
)
expect { migrator.migrate_inkbunny_users }.not_to change(
Domain::User::InkbunnyUser,
:count,
)
end
it "handles multiple users in batches" do
# Create a few more old users
additional_users =
2.times.map do |i|
create(
:domain_inkbunny_user,
name: "test_user_#{i}",
ib_user_id: 456 + i,
scanned_gallery_at: Time.current,
deep_update_log_entry: create(:http_log_entry),
shallow_update_log_entry: create(:http_log_entry),
)
end
expect { migrator.migrate_inkbunny_users }.to change(
Domain::User::InkbunnyUser,
:count,
).by(3)
expect(Domain::User::InkbunnyUser.count).to eq(3)
expect(Domain::User::InkbunnyUser.pluck(:ib_id)).to contain_exactly(
123,
456,
457,
)
# Verify all users were migrated correctly
([old_user] + additional_users).each do |old_user|
new_user =
Domain::User::InkbunnyUser.find_by(ib_id: old_user.ib_user_id)
expect_inkbunny_users_match(old_user, new_user)
end
end
it "handles users with avatars" do
avatar_log_entry =
create(
:http_log_entry,
uri_str: "https://example.com/avatar.jpg",
status_code: 200,
)
old_user.avatar_log_entry = avatar_log_entry
old_user.save!
migrator.migrate_inkbunny_users
new_user = Domain::User::InkbunnyUser.find_by(ib_id: old_user.ib_user_id)
expect_inkbunny_users_match(old_user, new_user)
expect(new_user.avatar).to be_present
expect(new_user.avatar.url_str).to eq(avatar_log_entry.uri_str)
expect(new_user.avatar.state).to eq("ok")
end
it "handles users with errored avatars" do
avatar_log_entry =
create(
:http_log_entry,
uri_str: "https://example.com/avatar.jpg",
status_code: 404,
)
old_user.avatar_log_entry = avatar_log_entry
old_user.save!
migrator.migrate_inkbunny_users
new_user = Domain::User::InkbunnyUser.find_by(ib_id: old_user.ib_user_id)
expect_inkbunny_users_match(old_user, new_user)
expect(new_user.avatar).to be_present
expect(new_user.avatar.url_str).to eq(avatar_log_entry.uri_str)
expect(new_user.avatar.state).to eq("error")
end
end
describe "#migrate_inkbunny_pools" do
let!(:creator) do
Domain::Inkbunny::User.create!(
name: "artist1",
ib_user_id: 123,
state: :ok,
state_detail: {
},
)
end
let!(:new_creator) do
Domain::User::InkbunnyUser.create!(
name: "artist1",
ib_id: 123,
state: "ok",
)
end
let!(:old_post1) do
post = create(:domain_inkbunny_post, creator: creator, ib_post_id: 1)
file = create(:domain_inkbunny_file, post: post)
post.files << file
post
end
let!(:old_post2) do
post = create(:domain_inkbunny_post, creator: creator, ib_post_id: 2)
file = create(:domain_inkbunny_file, post: post)
post.files << file
post
end
let!(:old_post3) do
post = create(:domain_inkbunny_post, creator: creator, ib_post_id: 3)
file = create(:domain_inkbunny_file, post: post)
post.files << file
post
end
let!(:new_post1) do
Domain::Post::InkbunnyPost.create!(
ib_id: old_post1.ib_post_id,
state: "ok",
rating: "general",
submission_type: "picture_pinup",
)
end
let!(:new_post2) do
Domain::Post::InkbunnyPost.create!(
ib_id: old_post2.ib_post_id,
state: "ok",
rating: "general",
submission_type: "picture_pinup",
)
end
let!(:new_post3) do
Domain::Post::InkbunnyPost.create!(
ib_id: old_post3.ib_post_id,
state: "ok",
rating: "general",
submission_type: "picture_pinup",
)
end
let!(:old_pool) do
pool = create(:domain_inkbunny_pool, ib_pool_id: 123)
# Create pool joins with sequential posts
pool.pool_joins.create!(
post: old_post1,
left_post: nil,
right_post: old_post2,
)
pool.pool_joins.create!(
post: old_post2,
left_post: old_post1,
right_post: old_post3,
)
pool.pool_joins.create!(
post: old_post3,
left_post: old_post2,
right_post: nil,
)
pool
end
it "migrates pools that don't exist in the new table" do
expect { migrator.migrate_inkbunny_pools }.to change(
Domain::PostGroup::InkbunnyPool,
:count,
).by(1)
new_pool =
Domain::PostGroup::InkbunnyPool.find_by(ib_id: old_pool.ib_pool_id)
expect_inkbunny_pools_match(old_pool, new_pool)
end
it "skips pools that already exist in the new table" do
# Create a pool in the new table first
Domain::PostGroup::InkbunnyPool.create!(ib_id: old_pool.ib_pool_id)
expect { migrator.migrate_inkbunny_pools }.not_to change(
Domain::PostGroup::InkbunnyPool,
:count,
)
end
it "handles multiple pools in batches" do
# Create a few more old pools
additional_pools =
2.times.map do |i|
pool = create(:domain_inkbunny_pool, ib_pool_id: 456 + i)
# Add some joins to each pool
pool.pool_joins.create!(
post: old_post1,
left_post: nil,
right_post: old_post2,
)
pool.pool_joins.create!(
post: old_post2,
left_post: old_post1,
right_post: nil,
)
pool
end
expect { migrator.migrate_inkbunny_pools }.to change(
Domain::PostGroup::InkbunnyPool,
:count,
).by(3)
expect(Domain::PostGroup::InkbunnyPool.count).to eq(3)
expect(Domain::PostGroup::InkbunnyPool.pluck(:ib_id)).to contain_exactly(
123,
456,
457,
)
# Verify all pools were migrated correctly
([old_pool] + additional_pools).each do |old_pool|
new_pool =
Domain::PostGroup::InkbunnyPool.find_by(ib_id: old_pool.ib_pool_id)
expect_inkbunny_pools_match(old_pool, new_pool)
end
end
it "handles pools without joins" do
pool_without_joins = create(:domain_inkbunny_pool, ib_pool_id: 789)
expect { migrator.migrate_inkbunny_pools }.to change(
Domain::PostGroup::InkbunnyPool,
:count,
).by(2)
new_pool =
Domain::PostGroup::InkbunnyPool.find_by(
ib_id: pool_without_joins.ib_pool_id,
)
expect_inkbunny_pools_match(pool_without_joins, new_pool)
end
it "maintains the correct post relationships in pool joins" do
migrator.migrate_inkbunny_pools
new_pool =
Domain::PostGroup::InkbunnyPool.find_by(ib_id: old_pool.ib_pool_id)
# Verify the sequence of posts is maintained
joins = new_pool.post_group_joins.sort_by { |j| j.post.ib_id }
# First join should link to second post
expect(joins[0].post.ib_id).to eq(old_post1.ib_post_id)
expect(joins[0].left_post).to be_nil
expect(joins[0].right_post.ib_id).to eq(old_post2.ib_post_id)
# Middle join should link to both first and third posts
expect(joins[1].post.ib_id).to eq(old_post2.ib_post_id)
expect(joins[1].left_post.ib_id).to eq(old_post1.ib_post_id)
expect(joins[1].right_post.ib_id).to eq(old_post3.ib_post_id)
# Last join should link to second post
expect(joins[2].post.ib_id).to eq(old_post3.ib_post_id)
expect(joins[2].left_post.ib_id).to eq(old_post2.ib_post_id)
expect(joins[2].right_post).to be_nil
end
end
end

View File

@@ -115,6 +115,18 @@ RSpec.describe Domain::Post::FaPost do
query = described_class.pluck(:id, :fa_id)
expect(query).to eq([[post.id, post.fa_id]])
end
it "can be ordered by an attribute" do
create(:domain_post_fa_post, fa_id: 1)
create(:domain_post_fa_post, fa_id: 2)
query =
described_class.select(:fa_id, :json_attributes).order(fa_id: :asc)
expect(query.map(&:fa_id)).to eq([1, 2])
query = described_class.order(fa_id: :desc)
expect(query.map(&:fa_id)).to eq([2, 1])
end
end
describe "factory" do

View File

@@ -0,0 +1,152 @@
# typed: false
require "rails_helper"
RSpec.describe Domain::User::FaUser, type: :model do
describe "validations" do
let(:user) { build(:domain_user_fa_user) }
it "is valid with valid attributes" do
expect(user).to be_valid
end
it "requires name" do
user.name = nil
expect(user).not_to be_valid
expect(user.errors[:name]).to include("can't be blank")
end
it "requires url_name" do
user.url_name = nil
expect(user).not_to be_valid
expect(user.errors[:url_name]).to include("can't be blank")
end
end
describe "initialization" do
let(:user) { described_class.new }
it "has default values" do
expect(user.name).to be_nil
expect(user.url_name).to be_nil
expect(user.full_name).to be_nil
expect(user.artist_type).to be_nil
expect(user.mood).to be_nil
expect(user.profile_html).to be_nil
expect(user.num_pageviews).to be_nil
expect(user.num_submissions).to be_nil
expect(user.num_comments_recieved).to be_nil
expect(user.num_comments_given).to be_nil
expect(user.num_journals).to be_nil
expect(user.num_favorites).to be_nil
expect(user.scanned_gallery_at).to be_nil
expect(user.scanned_page_at).to be_nil
expect(user.registered_at).to be_nil
expect(user.migrated_followed_users_at).to be_nil
end
end
describe "attributes" do
let(:user) { create(:domain_user_fa_user) }
it "can update all attributes" do
time = Time.current
user.full_name = "Full Name"
user.artist_type = "artist"
user.mood = "happy"
user.profile_html = "<p>Profile</p>"
user.num_pageviews = 1000
user.num_submissions = 50
user.num_comments_recieved = 200
user.num_comments_given = 150
user.num_journals = 10
user.num_favorites = 300
user.scanned_gallery_at = time
user.scanned_page_at = time
user.registered_at = time
user.migrated_followed_users_at = time
expect(user.save).to be true
user.reload
expect(user.full_name).to eq("Full Name")
expect(user.artist_type).to eq("artist")
expect(user.mood).to eq("happy")
expect(user.profile_html).to eq("<p>Profile</p>")
expect(user.num_pageviews).to eq(1000)
expect(user.num_submissions).to eq(50)
expect(user.num_comments_recieved).to eq(200)
expect(user.num_comments_given).to eq(150)
expect(user.num_journals).to eq(10)
expect(user.num_favorites).to eq(300)
expect(user.scanned_gallery_at).to be_within(1.second).of(time)
expect(user.scanned_page_at).to be_within(1.second).of(time)
expect(user.registered_at).to be_within(1.second).of(time)
expect(user.migrated_followed_users_at).to be_within(1.second).of(time)
end
end
describe "#to_param" do
let(:user) { build(:domain_user_fa_user, url_name: "artist123") }
it "returns nil when url_name is blank" do
user.url_name = nil
expect(user.to_param).to be_nil
user.url_name = ""
expect(user.to_param).to be_nil
end
it "returns fa/url_name when url_name is present" do
expect(user.to_param).to eq("fa/artist123")
end
end
describe "associations" do
let(:user) { create(:domain_user_fa_user) }
let!(:post1) { create(:domain_post_fa_post) }
let!(:post2) { create(:domain_post_fa_post) }
let!(:post3) { create(:domain_post_fa_post) }
let!(:faved_post1) { create(:domain_post_fa_post) }
let!(:faved_post2) { create(:domain_post_fa_post) }
let!(:unfaved_post) { create(:domain_post_fa_post) }
before do
# Create user_post_creations to associate posts with user
Domain::UserPostCreation.create!(user: user, post: post1)
Domain::UserPostCreation.create!(user: user, post: post2)
# Create user_post_favs to associate faved posts with user
Domain::UserPostFav.create!(user: user, post: faved_post1)
Domain::UserPostFav.create!(user: user, post: faved_post2)
end
describe "#posts" do
it "returns associated FA posts" do
expect(user.posts).to match_array([post1, post2])
expect(user.posts).not_to include(post3)
end
it "returns posts of correct type" do
expect(user.posts).to all(be_a(Domain::Post::FaPost))
end
end
describe "#faved_posts" do
it "returns faved FA posts" do
expect(user.faved_posts).to match_array([faved_post1, faved_post2])
expect(user.faved_posts).not_to include(unfaved_post)
end
it "returns posts of correct type" do
expect(user.faved_posts).to all(be_a(Domain::Post::FaPost))
end
it "keeps posts and faved posts separate" do
expect(user.faved_posts).not_to include(post1, post2)
expect(user.posts).not_to include(faved_post1, faved_post2)
end
end
end
end