在创建具有关系的模型时触发验证

时间:2016-03-05 13:24:04

标签: ruby-on-rails-4 activerecord

我的应用程序中有2个模型,UserNotification,如下所示:

class Notification < ActiveRecord::Base
  has_and_belongs_to_many :users

  validates_presence_of :content, on: :create
end
class User < ActiveRecord::Base
  has_and_belongs_to_many :notifications

  validates_presence_of :email
  validates_uniqueness_of :email
end

每当我要创建新通知时,我都会使用以下代码:

users = User.where(kind: params[:kinds])
unless user_ids.nil?
   users += User.where(id: user_ids)
end
@notification = Notification.create(content: notification[:content], user_ids: users.uniq)

这很好但我在日志上看到了很多数据库检查。这是正常的吗?有什么办法可以降低数据库访问量吗?

日志片段:

User Load (2.1ms)  SELECT DISTINCT "users".* FROM "users" WHERE "users"."kind" IN ('parent', 'student', 'teacher')
  (0.1ms)  begin transaction
User Exists (0.1ms)  SELECT  1 AS one FROM "users" WHERE ("users"."email" = '[REDACTED]' AND "users"."id" != 34) LIMIT 1
User Exists (0.1ms)  SELECT  1 AS one FROM "users" WHERE ("users"."email" = '[REDACTED]' AND "users"."id" != 36) LIMIT 1
User Exists (0.1ms)  SELECT  1 AS one FROM "users" WHERE ("users"."email" = '[REDACTED]' AND "users"."id" != 38) LIMIT 1
User Exists (0.1ms)  SELECT  1 AS one FROM "users" WHERE ("users"."email" = '[REDACTED]' AND "users"."id" != 40) LIMIT 1
...

SQL (0.4ms)  INSERT INTO "notifications" ("content", "created_at", "updated_at") VALUES (?, ?, ?)  [["content", "asdadasd"], ["created_at", "2016-03-05 13:18:27.285540"], ["updated_at", "2016-03-05 13:18:27.285540"]]

SQL (0.2ms)  INSERT INTO "notifications_users" ("user_id", "notification_id") VALUES (?, ?)  [["user_id", 34], ["notification_id", 843]]
SQL (0.1ms)  INSERT INTO "notifications_users" ("user_id", "notification_id") VALUES (?, ?)  [["user_id", 36], ["notification_id", 843]]
SQL (0.1ms)  INSERT INTO "notifications_users" ("user_id", "notification_id") VALUES (?, ?)  [["user_id", 38], ["notification_id", 843]]
SQL (0.1ms)  INSERT INTO "notifications_users" ("user_id", "notification_id") VALUES (?, ?)  [["user_id", 40], ["notification_id", 843]]
...

1 个答案:

答案 0 :(得分:0)

在我看来,第一个问题是每次要发送新通知时都要加载所有用户

即这条线:

users = User.where(kind: params[:kinds])

然后您向此对象添加更多用户,每次查找都会导致数据库调用以确定用户是否已存在。

您应该将所有用户ID检索到散列中,然后添加到此散列中(如果不是)。接下来,根据此哈希中的这些ID发送通知。