User different table for cached counters

This does not make the required changes to redirect to these
new properties yet.
This commit is contained in:
Kira 2019-06-02 07:49:38 -07:00
parent 91da0b849d
commit 05e4736bb5
15 changed files with 118 additions and 12 deletions

View File

@ -297,10 +297,16 @@ class ApplicationRecord < ActiveRecord::Base
concerning :UserMethods do
class_methods do
def user_status_counter(counter_name, options = {})
class_eval do
belongs_to :user_status, {foreign_key: :creator_id, primary_key: :user_id, counter_cache: counter_name}.merge(options)
end
end
def belongs_to_creator(options = {})
class_eval do
belongs_to :creator, options.merge(class_name: "User")
before_validation(on: :create) do |rec|
before_validation(on: :create) do |rec|
if rec.creator_id.nil?
rec.creator_id = CurrentUser.id
rec.creator_ip_addr = CurrentUser.ip_addr if rec.respond_to?(:creator_ip_addr=)

View File

@ -1,6 +1,7 @@
class Blip < ApplicationRecord
simple_versioning
belongs_to_creator
user_status_counter :blip_count
validates_presence_of :body
belongs_to :parent, class_name: "Blip", foreign_key: "response_to", optional: true
has_many :responses, class_name: "Blip", foreign_key: "response_to"

View File

@ -8,6 +8,7 @@ class Comment < ApplicationRecord
belongs_to :post
belongs_to_creator
belongs_to_updater
user_status_counter :comment_count
has_many :votes, :class_name => "CommentVote", :dependent => :destroy
after_create :update_last_commented_at_on_create
after_update(:if => ->(rec) {(!rec.is_deleted? || !rec.saved_change_to_is_deleted?) && CurrentUser.id != rec.creator_id}) do |rec|
@ -18,7 +19,7 @@ class Comment < ApplicationRecord
ModAction.log(:comment_delete, {comment_id: rec.id, user_id: rec.creator_id})
end
mentionable(
:message_field => :body,
:message_field => :body,
:title => ->(user_name) {"#{creator_name} mentioned you in a comment on post ##{post_id}"},
:body => ->(user_name) {"@#{creator_name} mentioned you in a \"comment\":/posts/#{post_id}#comment-#{id} on post ##{post_id}:\n\n[quote]\n#{DText.excerpt(body, "@"+user_name)}\n[/quote]\n"},
)

View File

@ -3,6 +3,7 @@ class Favorite < ApplicationRecord
end
belongs_to :post
belongs_to :user, counter_cache: 'favorite_count'
belongs_to :user
user_status_counter :favorite_count, foreign_key: :user_id
scope :for_user, ->(user_id) {where("user_id = #{user_id.to_i}")}
end

View File

@ -5,6 +5,7 @@ class ForumPost < ApplicationRecord
attr_readonly :topic_id
belongs_to_creator
belongs_to_updater
user_status_counter :forum_post_count
belongs_to :topic, :class_name => "ForumTopic"
has_many :votes, class_name: "ForumPostVote"
has_one :tag_alias
@ -28,7 +29,7 @@ class ForumPost < ApplicationRecord
ModAction.log(:forum_post_delete, {forum_post_id: rec.id, forum_topic_id: rec.topic_id, user_id: rec.creator_id})
end
mentionable(
:message_field => :body,
:message_field => :body,
:title => ->(user_name) {%{#{creator_name} mentioned you in topic ##{topic_id} (#{topic.title})}},
:body => ->(user_name) {%{@#{creator_name} mentioned you in topic ##{topic_id} ("#{topic.title}":[/forum_topics/#{topic_id}?page=#{forum_topic_page}]):\n\n[quote]\n#{DText.excerpt(body, "@"+user_name)}\n[/quote]\n}},
)
@ -102,7 +103,7 @@ class ForumPost < ApplicationRecord
super(options)
end
def hidden_attributes
super + [:text_index]
end

View File

@ -1,5 +1,6 @@
class NoteVersion < ApplicationRecord
belongs_to_updater :counter_cache => "note_update_count"
user_status_counter :note_count, foreign_key: :updater_id
belongs_to_updater
scope :for_user, ->(user_id) {where("updater_id = ?", user_id)}
def self.search(params)

View File

@ -4,6 +4,7 @@ class Pool < ApplicationRecord
array_attribute :post_ids, parse: /\d+/, cast: :to_i
belongs_to_creator
user_status_counter :pool_count
validates_uniqueness_of :name, case_sensitive: false, if: :name_changed?
validate :validate_name, if: :name_changed?

View File

@ -42,7 +42,8 @@ class Post < ApplicationRecord
belongs_to :updater, :class_name => "User", optional: true # this is handled in versions
belongs_to :approver, class_name: "User", optional: true
belongs_to :uploader, :class_name => "User", :counter_cache => "post_upload_count"
belongs_to :uploader, :class_name => "User"
user_status_counter :post_count, foreign_key: :uploader_id
belongs_to :parent, class_name: "Post", optional: true
has_one :upload, :dependent => :destroy
has_one :artist_commentary, :dependent => :destroy

View File

@ -2,7 +2,8 @@ class PostArchive < ApplicationRecord
extend Memoist
belongs_to :post
belongs_to_updater counter_cache: "post_update_count"
belongs_to_updater
user_status_counter :post_update_count, foreign_key: :updater_id
before_validation :fill_version, on: :create
before_validation :fill_changes, on: :create

View File

@ -17,7 +17,8 @@ class PostSet < ApplicationRecord
end
end
has_many :maintainers, class_name: "User", through: :post_set_maintainers
belongs_to_creator counter_cache: 'set_count'
belongs_to_creator
user_status_counter :set_count
validates_length_of :name, :shortname, in: 3..100, message: "must be between three and one hundred characters long"
validates_uniqueness_of :name, :shortname, case_sensitive: false, message: "is already taken"
@ -309,4 +310,4 @@ class PostSet < ApplicationRecord
include ValidationMethods
include AccessMethods
include PostMethods
end
end

6
app/models/user.rb Executable file → Normal file
View File

@ -72,6 +72,7 @@ class User < ApplicationRecord
before_create :promote_to_admin_if_first_user
before_create :customize_new_user
#after_create :notify_sock_puppets
after_create :create_user_status
has_many :feedback, :class_name => "UserFeedback", :dependent => :destroy
has_many :posts, :foreign_key => "uploader_id"
has_many :post_approvals, :dependent => :destroy
@ -84,7 +85,6 @@ class User < ApplicationRecord
has_one :api_key
has_one :dmail_filter
has_one :super_voter
has_many :note_versions, :foreign_key => "updater_id"
has_many :dmails, -> {order("dmails.id desc")}, :foreign_key => "owner_id"
has_many :saved_searches
@ -381,6 +381,10 @@ class User < ApplicationRecord
def level_class
"user-#{level_string.downcase}"
end
def create_user_status
UserStatus.create!(user_id: id)
end
end
module EmailMethods

View File

@ -0,0 +1,2 @@
class UserStatus < ApplicationRecord
end

View File

@ -2,6 +2,7 @@ class WikiPageVersion < ApplicationRecord
array_attribute :other_names
belongs_to :wiki_page
belongs_to_updater
user_status_counter :wiki_edit_count, foreign_key: :updater_id
belongs_to :artist, optional: true
delegate :visible?, :to => :wiki_page

View File

@ -0,0 +1,19 @@
class AddUserStatuses < ActiveRecord::Migration[5.2]
def change
create_table :user_statuses do |t|
t.timestamps
t.integer :user_id, index: true, null: false
t.integer :post_count, null: false, default: 0
t.integer :post_deleted_count, null: false, default: 0
t.integer :post_update_count, null: false, default: 0
t.integer :favorite_count, null: false, default: 0
t.integer :wiki_edit_count, null: false, default: 0
t.integer :note_count, null: false, default: 0
t.integer :forum_post_count, null: false, default: 0
t.integer :comment_count, null: false, default: 0
t.integer :pool_count, null: false, default: 0
t.integer :blip_count, null: false, default: 0
t.integer :set_count, null: false, default: 0
end
end
end

View File

@ -2515,6 +2515,48 @@ CREATE SEQUENCE public.user_password_reset_nonces_id_seq
ALTER SEQUENCE public.user_password_reset_nonces_id_seq OWNED BY public.user_password_reset_nonces.id;
--
-- Name: user_statuses; Type: TABLE; Schema: public; Owner: -
--
CREATE TABLE public.user_statuses (
id bigint NOT NULL,
created_at timestamp without time zone NOT NULL,
updated_at timestamp without time zone NOT NULL,
user_id integer NOT NULL,
post_count integer DEFAULT 0 NOT NULL,
post_deleted_count integer DEFAULT 0 NOT NULL,
post_update_count integer DEFAULT 0 NOT NULL,
favorite_count integer DEFAULT 0 NOT NULL,
wiki_edit_count integer DEFAULT 0 NOT NULL,
note_count integer DEFAULT 0 NOT NULL,
forum_post_count integer DEFAULT 0 NOT NULL,
comment_count integer DEFAULT 0 NOT NULL,
pool_count integer DEFAULT 0 NOT NULL,
blip_count integer DEFAULT 0 NOT NULL,
set_count integer DEFAULT 0 NOT NULL
);
--
-- Name: user_statuses_id_seq; Type: SEQUENCE; Schema: public; Owner: -
--
CREATE SEQUENCE public.user_statuses_id_seq
START WITH 1
INCREMENT BY 1
NO MINVALUE
NO MAXVALUE
CACHE 1;
--
-- Name: user_statuses_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: -
--
ALTER SEQUENCE public.user_statuses_id_seq OWNED BY public.user_statuses.id;
--
-- Name: users; Type: TABLE; Schema: public; Owner: -
--
@ -3097,6 +3139,13 @@ ALTER TABLE ONLY public.user_name_change_requests ALTER COLUMN id SET DEFAULT ne
ALTER TABLE ONLY public.user_password_reset_nonces ALTER COLUMN id SET DEFAULT nextval('public.user_password_reset_nonces_id_seq'::regclass);
--
-- Name: user_statuses id; Type: DEFAULT; Schema: public; Owner: -
--
ALTER TABLE ONLY public.user_statuses ALTER COLUMN id SET DEFAULT nextval('public.user_statuses_id_seq'::regclass);
--
-- Name: users id; Type: DEFAULT; Schema: public; Owner: -
--
@ -3638,6 +3687,14 @@ ALTER TABLE ONLY public.user_password_reset_nonces
ADD CONSTRAINT user_password_reset_nonces_pkey PRIMARY KEY (id);
--
-- Name: user_statuses user_statuses_pkey; Type: CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY public.user_statuses
ADD CONSTRAINT user_statuses_pkey PRIMARY KEY (id);
--
-- Name: users users_pkey; Type: CONSTRAINT; Schema: public; Owner: -
--
@ -4698,6 +4755,13 @@ CREATE INDEX index_user_name_change_requests_on_original_name ON public.user_nam
CREATE INDEX index_user_name_change_requests_on_user_id ON public.user_name_change_requests USING btree (user_id);
--
-- Name: index_user_statuses_on_user_id; Type: INDEX; Schema: public; Owner: -
--
CREATE INDEX index_user_statuses_on_user_id ON public.user_statuses USING btree (user_id);
--
-- Name: index_users_on_email; Type: INDEX; Schema: public; Owner: -
--
@ -5057,6 +5121,7 @@ INSERT INTO "schema_migrations" (version) VALUES
('20190428132152'),
('20190430120155'),
('20190510184237'),
('20190510184245');
('20190510184245'),
('20190602115848');