:normal results in an error:
User Load (3.1ms) SELECT "users".* FROM "users"
(0.4ms) SELECT "category_users"."category_id" FROM "category_users" WHERE "category_users"."user_id" = 121 AND "category_users"."notification_level" IS NULL
(0.9ms) SELECT "categories"."id" FROM "categories" WHERE (id in (10))
SQL (0.8ms) INSERT INTO "category_users" ("user_id", "category_id") VALUES (121, 10) RETURNING "id" [["user_id", 121], ["category_id", 10]]
ActiveRecord::StatementInvalid: PG::NotNullViolation: ERROR: null value in column "notification_level" violates not-null constraint
DETAIL: Failing row contains (1271, 10, 121, null).
: INSERT INTO "category_users" ("user_id", "category_id") VALUES (121, 10) RETURNING "id"
from /home/vagrant/.rvm/gems/ruby-2.3.1/gems/rack-mini-profiler-0.10.1/lib/patches/db/pg.rb:90:in `exec'
My guess is that I don’t really want to set it as
:regular but somehow to set it as
The query is along the lines of:
builder.where('notification_level = :tracking')
Later on doing this does nothing cause there is no
watching var to substitute.
@sam, I’m afraid I don’t understand your answer. I’ve taken us a bit astray from the OT, but this is what I’m struggling with:
What are you trying to do, delete all the category user records for all users that have it set to watching and 5?
CategoryUser.where(category_id: 5, notification_level: CategoryUser.notification_levels[:watching]).delete_all
I wouldn’t of said it like that, but YES! Holy cow, yes.
It seems to do just what it says on the tin. Any adverse side-effects I should be aware of before trying this on production?
well, it junks that user pref, any user that set watching on category 5, will no longer have watching on category 5.
That sounds about right
Thanks to everyone here for helping me. For those playing at home, here’s a summary of the last 15 posts or so.
How to make all users watch (or unwatch) a specific category through the rails console
Set your parameters:
# Levels → :tracking :watching :watching_first_post :muted
level = :watching
category_slug = "announcements"
And then, to make everyone watch (or whatever level you set) this category:
User.all.each do |user| CategoryUser.batch_set(user, level, [Category.find_by_slug(category_slug)]) end
Or to make everyone unwatch (or whatever level you set) this category:
CategoryUser.where(category_id: Category.find_by_slug(category_slug), notification_level: CategoryUser.notification_levels[level]).delete_all
And there you have it!
Warning: unlike the OP, this is a destructive change in the sense that it disregards users’ current settings.
This works for top-level categories, but if I use the slug of a sub-category, it gives me
> category = Category.find_by_slug(category_slug)
How do you achieve the same for sub-categories?
I think I figured it out (thanks to this hint). This seems to work, but there might be a more elegant way (I don’t know how to define and hand over an array)
# levels: :watching :watching_first_post
level = :watching
category_slug = "local-news"
parent_category_slug = "news" # <== added
category = Category.find_by_slug(category_slug, parent_category_slug)
group_name = "trust_level_0" # all users
group = group = Group.find_by_name(group_name)
group.users.each do |user|
watched_categories = CategoryUser.lookup(user, level).pluck(:category_id)
category.id) unless watched_categories.include?(category.id)
Is there a way to re-apply all default watching/tracking/email preferences to all users?
Not per-category as the commands here describe, but more like “here are the defaults for new users… go ahead & apply them to all users now”?
If I can save the time I have spent with this thread to someone in the future…
If you want to reset the notification level of a
subcategory for all users from e.g. “muted” to “regular” (being
regular a special case), this is what you need to do:
./launcher enter app
And then paste your version of
level = :muted
category_slug = "cats" # this is the subcategory
parent_category_slug = "mammals" # this is the parent category
CategoryUser.where(category_id: Category.find_by_slug(category_slug, parent_category_slug), notification_level: CategoryUser.notification_levels[level]).delete_all
Can this be modified to work in group PM inboxes? For example, I was on an extended vacation, and I’m now returning. I updated my notification state for a shared inbox to “tracking” so I didn’t have thousands of green notifications, and now I want to update the state for all messages back to “watching”.
@sam, here’s the code to update the notification level for PMs historically. The following placeholders must be replaced:
TopicUser.where('notification_level < 3 and user_id = <user_id> and topic_id in (select topic_id from topic_allowed_groups where group_id in (<group_id_1>,<group_id_2>) )').update_all(notification_level: 3)
Step 3, run a query to backfill changes
Say I want to set categories watching first post to on a certain category, I look up per step one and find it is 5.
INSERT INTO category_users(category_id, user_id, notification_level)
SELECT 5, u.id, 4
FROM users u
LEFT JOIN category_users cu ON cu.category_id = 5 AND cu.user_id = u.id
WHERE cu.user_id IS NULL;
The above query sets it on all users that do not have an explicit default for the category already set, this means you can re-run it if needed.
Assuming that this still works, I’m wondering whether category permissions will be honoured here.
I have a number of restricted categories and whoever has access to any of those should be watching first post by default. So if I follow the above steps for each of those categories, will only only users who actually hsve access be watching them?
Category permissions are 100% followed.
Okay, just to double check: am I right in assuming that I can use the above procedure to add the category in question to
all users but if a user doesn’t have access to that category it will remain ineffective and invisible for that user until the user gains access?
(My reasoning is based on
default categories watching (etc) works
That is my understand, yes.
How can this be made to work with a two-container setup? If I enter
data there is no rails. And if I enter
web_only I get
NoMethodError: undefined method `id' for nil:NilClass.
Hm, I was searching for “staff”, to be on the safe side:
# rails c
 pry(main)> Category.find_by(name: "staff").id
NoMethodError: undefined method `id' for nil:NilClass
from (pry):1:in `__pry__'
Edit: Okay, got it: it’s case sensitive. This works:
Yesterday I discovered where our email volume of 100K+/mo was coming from… All new users were getting set as subscribed to our “General karting” category…
So I need to correct that…
I need some help with the syntax of part 1 in the OP. Bare with me here… I’m not exactly sure what I’m doing wrong…
I tried both " and ’ for quotations, but otherwise, I’m not sure what I need to correct in my syntax
 pry(main)> % Category.find_by(name: "General Karting").id
SyntaxError: unexpected ')', expecting end-of-input
...ind_by(name: "General Karting").id
 pry(main)> % Category.find_by(name: 'General Karting').id
SyntaxError: unexpected ')', expecting end-of-input
...ind_by(name: 'General Karting').id