diff --git a/app/models/dmail.rb b/app/models/dmail.rb index bc0d36683..abefad108 100644 --- a/app/models/dmail.rb +++ b/app/models/dmail.rb @@ -253,10 +253,9 @@ class Dmail < ApplicationRecord end def mark_as_read! - update_column(:is_read, true) - - unless Dmail.where(:is_read => false, :owner_id => CurrentUser.user.id).exists? - CurrentUser.user.update_attribute(:has_mail, false) + owner.dmails.unread.count.tap do |unread_count| + update_column(:is_read, true) + owner.update(has_mail: (unread_count > 0), unread_dmail_count: unread_count) end end @@ -276,7 +275,7 @@ class Dmail < ApplicationRecord def update_recipient if owner_id != CurrentUser.user.id && !is_deleted? && !is_read? - to.update_attribute(:has_mail, true) + to.update(has_mail: true, unread_dmail_count: to.dmails.unread.count) end end diff --git a/app/models/user.rb b/app/models/user.rb index b55226113..d7b9933a4 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -928,7 +928,7 @@ class User < ApplicationRecord def dmail_count if has_mail? - "(#{dmails.unread.count})" + "(#{unread_dmail_count})" else "" end diff --git a/db/migrate/20180425194016_add_dmail_count_to_users.rb b/db/migrate/20180425194016_add_dmail_count_to_users.rb new file mode 100644 index 000000000..beeb1eb26 --- /dev/null +++ b/db/migrate/20180425194016_add_dmail_count_to_users.rb @@ -0,0 +1,8 @@ +class AddDmailCountToUsers < ActiveRecord::Migration[5.1] + def change + ApplicationRecord.without_timeout do + add_column :users, :unread_dmail_count, :integer, default: 0, null: false + execute "update users set unread_dmail_count = (select count(*) from dmails where dmails.owner_id = users.id and dmails.is_read = false)" + end + end +end diff --git a/db/structure.sql b/db/structure.sql index 764ad9659..aad387a7a 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -2103,6 +2103,39 @@ CREATE SEQUENCE public.favorites_id_seq ALTER SEQUENCE public.favorites_id_seq OWNED BY public.favorites.id; +-- +-- Name: forum_post_votes; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.forum_post_votes ( + id bigint NOT NULL, + forum_post_id integer NOT NULL, + creator_id integer NOT NULL, + score integer NOT NULL, + created_at timestamp without time zone NOT NULL, + updated_at timestamp without time zone NOT NULL +); + + +-- +-- Name: forum_post_votes_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public.forum_post_votes_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- Name: forum_post_votes_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.forum_post_votes_id_seq OWNED BY public.forum_post_votes.id; + + -- -- Name: forum_posts; Type: TABLE; Schema: public; Owner: - -- @@ -3233,7 +3266,8 @@ furry -rating:s'::text, per_page integer DEFAULT 20 NOT NULL, custom_style text, bit_prefs bigint DEFAULT 0 NOT NULL, - last_ip_addr inet + last_ip_addr inet, + unread_dmail_count integer DEFAULT 0 NOT NULL ); @@ -4166,6 +4200,13 @@ ALTER TABLE ONLY public.favorites_98 ALTER COLUMN id SET DEFAULT nextval('public ALTER TABLE ONLY public.favorites_99 ALTER COLUMN id SET DEFAULT nextval('public.favorites_id_seq'::regclass); +-- +-- Name: forum_post_votes id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.forum_post_votes ALTER COLUMN id SET DEFAULT nextval('public.forum_post_votes_id_seq'::regclass); + + -- -- Name: forum_posts id; Type: DEFAULT; Schema: public; Owner: - -- @@ -4550,6 +4591,14 @@ ALTER TABLE ONLY public.favorites ADD CONSTRAINT favorites_pkey PRIMARY KEY (id); +-- +-- Name: forum_post_votes forum_post_votes_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.forum_post_votes + ADD CONSTRAINT forum_post_votes_pkey PRIMARY KEY (id); + + -- -- Name: forum_posts forum_posts_pkey; Type: CONSTRAINT; Schema: public; Owner: - -- @@ -4710,6 +4759,14 @@ ALTER TABLE ONLY public.saved_searches ADD CONSTRAINT saved_searches_pkey PRIMARY KEY (id); +-- +-- Name: schema_migrations schema_migrations_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.schema_migrations + ADD CONSTRAINT schema_migrations_pkey PRIMARY KEY (version); + + -- -- Name: super_voters super_voters_pkey; Type: CONSTRAINT; Schema: public; Owner: - -- @@ -5051,20 +5108,6 @@ CREATE INDEX index_comments_on_ip_addr ON public.comments USING btree (ip_addr); CREATE INDEX index_comments_on_post_id ON public.comments USING btree (post_id); --- --- Name: index_delayed_jobs_on_locked_at; Type: INDEX; Schema: public; Owner: - --- - -CREATE INDEX index_delayed_jobs_on_locked_at ON public.delayed_jobs USING btree (locked_at); - - --- --- Name: index_delayed_jobs_on_locked_by; Type: INDEX; Schema: public; Owner: - --- - -CREATE INDEX index_delayed_jobs_on_locked_by ON public.delayed_jobs USING btree (locked_by); - - -- -- Name: index_delayed_jobs_on_run_at; Type: INDEX; Schema: public; Owner: - -- @@ -6528,6 +6571,20 @@ CREATE INDEX index_favorites_9_on_post_id ON public.favorites_9 USING btree (pos CREATE INDEX index_favorites_9_on_user_id ON public.favorites_9 USING btree (user_id); +-- +-- Name: index_forum_post_votes_on_forum_post_id; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_forum_post_votes_on_forum_post_id ON public.forum_post_votes USING btree (forum_post_id); + + +-- +-- Name: index_forum_post_votes_on_forum_post_id_and_creator_id; Type: INDEX; Schema: public; Owner: - +-- + +CREATE UNIQUE INDEX index_forum_post_votes_on_forum_post_id_and_creator_id ON public.forum_post_votes USING btree (forum_post_id, creator_id); + + -- -- Name: index_forum_posts_on_creator_id; Type: INDEX; Schema: public; Owner: - -- @@ -6934,6 +6991,13 @@ CREATE INDEX index_posts_on_parent_id ON public.posts USING btree (parent_id); CREATE INDEX index_posts_on_pixiv_id ON public.posts USING btree (pixiv_id) WHERE (pixiv_id IS NOT NULL); +-- +-- Name: index_posts_on_source; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_posts_on_source ON public.posts USING btree (lower((source)::text)); + + -- -- Name: index_posts_on_source_pattern; Type: INDEX; Schema: public; Owner: - -- @@ -6955,6 +7019,13 @@ CREATE INDEX index_posts_on_tags_index ON public.posts USING gin (tag_index); CREATE INDEX index_posts_on_uploader_id ON public.posts USING btree (uploader_id); +-- +-- Name: index_posts_on_uploader_ip_addr; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_posts_on_uploader_ip_addr ON public.posts USING btree (uploader_ip_addr); + + -- -- Name: index_saved_searches_on_labels; Type: INDEX; Schema: public; Owner: - -- @@ -7193,13 +7264,6 @@ CREATE INDEX index_wiki_pages_on_title_pattern ON public.wiki_pages USING btree CREATE INDEX index_wiki_pages_on_updated_at ON public.wiki_pages USING btree (updated_at); --- --- Name: unique_schema_migrations; Type: INDEX; Schema: public; Owner: - --- - -CREATE UNIQUE INDEX unique_schema_migrations ON public.schema_migrations USING btree (version); - - -- -- Name: favorites insert_favorites_trigger; Type: TRIGGER; Schema: public; Owner: - -- @@ -7428,6 +7492,8 @@ INSERT INTO "schema_migrations" (version) VALUES ('20171230220225'), ('20180113211343'), ('20180116001101'), -('20180403231351'); +('20180403231351'), +('20180413224239'), +('20180425194016'); diff --git a/test/unit/dmail_test.rb b/test/unit/dmail_test.rb index 45594f52a..7c3ad420f 100644 --- a/test/unit/dmail_test.rb +++ b/test/unit/dmail_test.rb @@ -174,18 +174,20 @@ class DmailTest < ActiveSupport::TestCase end should "notify the recipient he has mail" do - @recipient = FactoryBot.create(:user) - dmail = FactoryBot.create(:dmail, :owner => @recipient) - recipient = dmail.to + recipient = FactoryBot.create(:user) + Dmail.create_split(title: "hello", body: "hello", to_id: recipient.id) + dmail = Dmail.where(owner_id: recipient.id).last recipient.reload assert(recipient.has_mail?) + assert_equal(1, recipient.unread_dmail_count) CurrentUser.scoped(recipient) do dmail.mark_as_read! end recipient.reload - assert(!recipient.has_mail?) + refute(recipient.has_mail?) + assert_equal(0, recipient.unread_dmail_count) end context "that is automated" do