fixed select, pluck
This commit is contained in:
@@ -230,10 +230,12 @@ class Domain::MigrateToDomain
|
||||
old_post_fa_ids = old_user.fav_posts.pluck(:fa_id)
|
||||
new_post_ids = Domain::Post::FaPost.where(fa_id: old_post_fa_ids).pluck(:id)
|
||||
|
||||
Domain::UserPostFav.upsert_all(
|
||||
new_post_ids.map { |post_id| { user_id: user.id, post_id: } },
|
||||
unique_by: %i[user_id post_id],
|
||||
)
|
||||
new_post_ids.each_slice(10_000) do |post_ids|
|
||||
Domain::UserPostFav.upsert_all(
|
||||
post_ids.map { |post_id| { user_id: user.id, post_id: } },
|
||||
unique_by: %i[user_id post_id],
|
||||
)
|
||||
end
|
||||
|
||||
if user.faved_posts.count != old_user.fav_posts.count
|
||||
logger.error(
|
||||
@@ -261,10 +263,12 @@ class Domain::MigrateToDomain
|
||||
new_user_ids =
|
||||
Domain::User::FaUser.where(url_name: followed_user_url_names).pluck(:id)
|
||||
|
||||
Domain::UserUserFollow.upsert_all(
|
||||
new_user_ids.map { |user_id| { from_id: user.id, to_id: user_id } },
|
||||
unique_by: %i[from_id to_id],
|
||||
)
|
||||
new_user_ids.each_slice(10_000) do |user_ids|
|
||||
Domain::UserUserFollow.upsert_all(
|
||||
user_ids.map { |user_id| { from_id: user.id, to_id: user_id } },
|
||||
unique_by: %i[from_id to_id],
|
||||
)
|
||||
end
|
||||
|
||||
if user.following_users.count != old_user.follows.count
|
||||
logger.error(
|
||||
|
||||
@@ -42,6 +42,35 @@ class Arel::Visitors::ToSql
|
||||
)
|
||||
end
|
||||
|
||||
require "active_record/relation/query_methods"
|
||||
module ActiveRecord::QueryMethods
|
||||
extend T::Sig
|
||||
prepend(
|
||||
Module.new do
|
||||
extend T::Sig
|
||||
|
||||
sig { params(field: T.untyped).returns(T.untyped) }
|
||||
def arel_column(field)
|
||||
klass = T.cast(T.unsafe(self).klass, T.class_of(ActiveRecord::Base))
|
||||
if attribute_def =
|
||||
AttrJsonRecordAliases::ImplHelper.get_json_attr_def(klass, field)
|
||||
attr_type_cast =
|
||||
T.unsafe(klass).json_attribute_type_cast(attribute_def.type.type)
|
||||
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)}",
|
||||
)
|
||||
else
|
||||
super
|
||||
end
|
||||
end
|
||||
end,
|
||||
)
|
||||
end
|
||||
|
||||
module AttrJsonRecordAliases
|
||||
extend T::Sig
|
||||
extend T::Helpers
|
||||
@@ -68,14 +97,8 @@ module AttrJsonRecordAliases
|
||||
|
||||
sig { params(name: T.untyped, value: T.untyped).returns(T.untyped) }
|
||||
def write_attribute(name, value)
|
||||
klass = self.class
|
||||
ret = super(name, value)
|
||||
registry =
|
||||
T.cast(
|
||||
T.unsafe(klass).attr_json_registry,
|
||||
AttrJson::AttributeDefinition::Registry,
|
||||
)
|
||||
if attribute_def = registry[name.to_sym]
|
||||
if attribute_def = ImplHelper.get_json_attr_def(self.class, name)
|
||||
public_send(attribute_def.container_attribute)[
|
||||
attribute_def.store_key
|
||||
] = read_attribute(name)
|
||||
@@ -83,6 +106,28 @@ module AttrJsonRecordAliases
|
||||
ret
|
||||
end
|
||||
|
||||
module ImplHelper
|
||||
extend T::Sig
|
||||
|
||||
sig do
|
||||
params(klass: T.class_of(ActiveRecord::Base), field: T.untyped).returns(
|
||||
T.nilable(AttrJson::AttributeDefinition),
|
||||
)
|
||||
end
|
||||
def self.get_json_attr_def(klass, field)
|
||||
if klass < AttrJsonRecordAliases
|
||||
registry =
|
||||
T.cast(
|
||||
T.unsafe(klass).attr_json_registry,
|
||||
AttrJson::AttributeDefinition::Registry,
|
||||
)
|
||||
registry[field.to_sym]
|
||||
else
|
||||
nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
module ClassMethods
|
||||
extend T::Sig
|
||||
extend T::Helpers
|
||||
|
||||
@@ -1,13 +1,27 @@
|
||||
# typed: strict
|
||||
#
|
||||
class CreateDomainPosts < ActiveRecord::Migration[7.2]
|
||||
class CreateUnifiedDomainTables < ActiveRecord::Migration[7.2]
|
||||
extend T::Sig
|
||||
|
||||
POST_TYPES = %w[
|
||||
Domain::Post::FaPost
|
||||
Domain::Post::E621Post
|
||||
Domain::Post::InkbunnyPost
|
||||
Domain::Post::SofurryPost
|
||||
]
|
||||
|
||||
USER_TYPES = %w[
|
||||
Domain::User::FaUser
|
||||
Domain::User::E621User
|
||||
Domain::User::InkbunnyUser
|
||||
Domain::User::SofurryUser
|
||||
]
|
||||
|
||||
sig { void }
|
||||
def change
|
||||
reversible do |dir|
|
||||
dir.up do
|
||||
execute "CREATE TYPE domain_post_type AS ENUM ('Domain::Post::FaPost', 'Domain::Post::E621Post')"
|
||||
execute "CREATE TYPE domain_post_type AS ENUM (#{POST_TYPES.map { |t| "'#{t}'" }.join(", ")})"
|
||||
end
|
||||
|
||||
dir.down { execute "DROP TYPE domain_post_type" }
|
||||
@@ -23,7 +37,7 @@ class CreateDomainPosts < ActiveRecord::Migration[7.2]
|
||||
|
||||
reversible do |dir|
|
||||
dir.up do
|
||||
execute "CREATE TYPE domain_user_type AS ENUM ('Domain::User::FaUser', 'Domain::User::E621User')"
|
||||
execute "CREATE TYPE domain_user_type AS ENUM (#{USER_TYPES.map { |t| "'#{t}'" }.join(", ")})"
|
||||
end
|
||||
|
||||
dir.down { execute "DROP TYPE domain_user_type" }
|
||||
@@ -99,7 +99,9 @@ COMMENT ON EXTENSION vector IS 'vector data type and ivfflat access method';
|
||||
|
||||
CREATE TYPE public.domain_post_type AS ENUM (
|
||||
'Domain::Post::FaPost',
|
||||
'Domain::Post::E621Post'
|
||||
'Domain::Post::E621Post',
|
||||
'Domain::Post::InkbunnyPost',
|
||||
'Domain::Post::SofurryPost'
|
||||
);
|
||||
|
||||
|
||||
@@ -109,7 +111,9 @@ CREATE TYPE public.domain_post_type AS ENUM (
|
||||
|
||||
CREATE TYPE public.domain_user_type AS ENUM (
|
||||
'Domain::User::FaUser',
|
||||
'Domain::User::E621User'
|
||||
'Domain::User::E621User',
|
||||
'Domain::User::InkbunnyUser',
|
||||
'Domain::User::SofurryUser'
|
||||
);
|
||||
|
||||
|
||||
|
||||
@@ -83,15 +83,20 @@ namespace :e621 do
|
||||
# puts Domain::Post::E621Post.where(e621_id: 5_350_363).explain.inspect
|
||||
# puts Domain::Post::FaPost.where(fa_id: 52_801_830).explain.inspect
|
||||
# puts Domain::Fa::Post.where(fa_id: 52_801_830).explain.inspect
|
||||
puts Domain::Fa::Post
|
||||
.joins(
|
||||
"
|
||||
LEFT JOIN domain_posts ON domain_fa_posts.fa_id =
|
||||
(domain_posts.json_attributes->>'fa_id')::integer
|
||||
",
|
||||
)
|
||||
.where(domain_posts: { id: nil, type: "Domain::Post::FaPost" })
|
||||
puts Domain::Post::FaPost
|
||||
.select(:fa_id)
|
||||
.where(fa_id: 52_801_830)
|
||||
.explain
|
||||
.inspect
|
||||
# puts Domain::Fa::Post
|
||||
# .joins(
|
||||
# "
|
||||
# LEFT JOIN domain_posts ON domain_fa_posts.fa_id =
|
||||
# (domain_posts.json_attributes->>'fa_id')::integer
|
||||
# ",
|
||||
# )
|
||||
# .where(domain_posts: { id: nil, type: "Domain::Post::FaPost" })
|
||||
# .explain
|
||||
# .inspect
|
||||
end
|
||||
end
|
||||
|
||||
@@ -101,6 +101,20 @@ RSpec.describe Domain::Post::FaPost do
|
||||
new_post = described_class.new
|
||||
expect(new_post.keywords).to eq([])
|
||||
end
|
||||
|
||||
it "can be selected by an attribute" do
|
||||
post = create(:domain_post_fa_post)
|
||||
query = described_class.where(fa_id: post.fa_id)
|
||||
expect(query.count).to eq(1)
|
||||
query =
|
||||
described_class.select(:fa_id, :json_attributes).where(
|
||||
fa_id: post.fa_id,
|
||||
)
|
||||
expect(query.map(&:fa_id)).to eq([post.fa_id])
|
||||
|
||||
query = described_class.pluck(:id, :fa_id)
|
||||
expect(query).to eq([[post.id, post.fa_id]])
|
||||
end
|
||||
end
|
||||
|
||||
describe "factory" do
|
||||
|
||||
Reference in New Issue
Block a user