Rails 命令将用户批量提升为 TL2 吗?

你好,我为此开启一个新话题,因为我认为我在 上一个话题 中关于此问题的提问被忽略了,尽管我当时将其标记为已解决,但实际上并未解决。

情况如下:我迁移到了 Discourse,旧论坛的所有成员都只有 TL1 级别,他们觉得这不公平,因此我想通过调整要求将他们全部提升到 TL2。其中很多人处于非活跃状态,因为在迁移前我不得不先停用这些账户。

我将 TL2 的要求改为仅基于发帖数,并将访问天数设为 0。

10 天后,只有少数用户被提升,看来用户必须登录或回复帖子,TL2 的检查才会触发。(我尚未确定具体是哪一个条件)

我很希望能将旧论坛的所有前成员都授予 TL2 状态,请问是否有办法在某个地方运行命令来实现这一点?例如遍历所有用户,如果满足新的 TL2 条件就提升他们。

非常感谢您的帮助和见解!:slight_smile:

也许:

users = User.where('admin = false')
users.update_all(trust_level: 2)

该查询也会将所有版主更改为信任等级 2。

我不确定 @Queth 是否真的想这么做。

有一个如何批量将所有用户从较低信任级别移动到较高级别(反之亦然)的操作指南:

非常感谢你们的快速回复!

@Canapin, @neounix

我不介意暂时将模组更改为 tl2,之后我可以手动设置它们的信任等级。我认为这不会影响模组的功能吧?会影响吗?

@dax

谢谢!我们讨论的是 20,000 名用户,迁移后有 10,000 名用户处于 tl1,另外 10,000 名用户为 0。我只想提升那些 tl1 用户的等级,我可以用这个查询做到,对吧?

User.exec_sql("UPDATE users SET trust_level = 2 WHERE trust_level IN ( 1)")

另外还有一点,在此期间已经有“真实”的新成员注册了,我不希望他们在没有赢得信任的情况下就被提升到 tl2 ;)。

有没有办法加入某种注册日期条件?例如,所有在 2020 年 3 月 17 日之前注册的 tl1 用户?

是的,@Queth,需要我发布一份用户表结构的副本,以便你查看所有不同的字段吗?

更新:这是 @Queth 的表结构……从表描述中你可以看到有很多选择:)

users 表
discourse=# \d users

                                                Table "public.users"
          Column           |            Type             | Collation | Nullable |              Default              
---------------------------+-----------------------------+-----------+----------+-----------------------------------
 id                        | integer                     |           | not null | nextval('users_id_seq'::regclass)
 username                  | character varying(60)       |           | not null | 
 created_at                | timestamp without time zone |           | not null | 
 updated_at                | timestamp without time zone |           | not null | 
 name                      | character varying           |           |          | 
 seen_notification_id      | integer                     |           | not null | 0
 last_posted_at            | timestamp without time zone |           |          | 
 password_hash             | character varying(64)       |           |          | 
 salt                      | character varying(32)       |           |          | 
 active                    | boolean                     |           | not null | false
 username_lower            | character varying(60)       |           | not null | 
 last_seen_at              | timestamp without time zone |           |          | 
 admin                     | boolean                     |           | not null | false
 last_emailed_at           | timestamp without time zone |           |          | 
 trust_level               | integer                     |           | not null | 
 approved                  | boolean                     |           | not null | false
 approved_by_id            | integer                     |           |          | 
 approved_at               | timestamp without time zone |           |          | 
 previous_visit_at         | timestamp without time zone |           |          | 
 suspended_at              | timestamp without time zone |           |          | 
 suspended_till            | timestamp without time zone |           |          | 
 date_of_birth             | date                        |           |          | 
 views                     | integer                     |           | not null | 0
 flag_level                | integer                     |           | not null | 0
 ip_address                | inet                        |           |          | 
 moderator                 | boolean                     |           |          | false
 title                     | character varying           |           |          | 
 uploaded_avatar_id        | integer                     |           |          | 
 locale                    | character varying(10)       |           |          | 
 primary_group_id          | integer                     |           |          | 
 registration_ip_address   | inet                        |           |          | 
 staged                    | boolean                     |           | not null | false
 first_seen_at             | timestamp without time zone |           |          | 
 silenced_till             | timestamp without time zone |           |          | 
 group_locked_trust_level  | integer                     |           |          | 
 manual_locked_trust_level | integer                     |           |          | 
 secure_identifier         | character varying           |           |          | 
Indexes:
    "users_pkey" PRIMARY KEY, btree (id)
    "index_users_on_secure_identifier" UNIQUE, btree (secure_identifier)
    "index_users_on_username" UNIQUE, btree (username)
    "index_users_on_username_lower" UNIQUE, btree (username_lower)
    "idx_users_admin" btree (id) WHERE admin
    "idx_users_moderator" btree (id) WHERE moderator
    "index_users_on_last_posted_at" btree (last_posted_at)
    "index_users_on_last_seen_at" btree (last_seen_at)
    "index_users_on_uploaded_avatar_id" btree (uploaded_avatar_id)
Referenced by:
    TABLE "user_security_keys" CONSTRAINT "fk_rails_90999b0454" FOREIGN KEY (user_id) REFERENCES users(id)
    TABLE "poll_votes" CONSTRAINT "fk_rails_b64de9b025" FOREIGN KEY (user_id) REFERENCES users(id)
    TABLE "bookmarks" CONSTRAINT "fk_rails_c1ff6fa4ac" FOREIGN KEY (user_id) REFERENCES users(id)

在执行 UPDATE 之前,先执行 SELECT 并确保查询结果符合预期,这始终是个好习惯:) 在开始对数据库进行批量修改之前,请务必先进行完整备份。即使是顶尖高手也会因手滑而出错。专家与新手的主要区别之一就是:专家总是先备份再操作:)

感谢 @neounix

能否帮我确认一下正确的查询语句?因为我不太清楚该怎么做……可能需要在某处包含类似下面的内容:

Where user created at < [2020 年 3 月 17 日,但需正确格式化]

我很乐意帮忙;但有些事情由你自己做点功课会更简单(也更好)。你已经掌握了拼图的所有碎片,所以我的建议是花点时间学习如何编写 SQL 查询。说实话,这只是 PostgreSQL SQL 的基础知识,网上有无数教程可以找到。

重复那些“教程 101”类的内容,尤其是信息很容易被他人通过自己的谷歌搜索找到的内容,并不是我的风格。这只是我个人的做法。感谢您的理解,也请原谅我的直率。

注意:SQL 自 1974 年(即 46 年前)就已存在。如果你要管理基于数据库的应用程序,具备基本的 SQL 知识是一件好事。

谢谢 :slight_smile:
嗯,我确实有一些基础知识,但自己从头编写查询语句仍然让我更倾向于从可信来源复制粘贴,而不是尝试自己构思。

不过,还是要感谢这些基础模块!

在执行 UPDATE 之前,先执行 SELECT 并确保查询结果符合预期,这始终是个好主意 :slight_smile:。此外,在进行大规模数据库修改之前,务必备份完整数据。