2016-03-05 21 views
0

模型我在我的應用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 

每當我要創建一個新的通知,我使用下面的代碼:

​​

這工作正常,但我看到很多數據庫檢查日誌。這是正常的嗎?有什麼我可以做的,以降低數據庫訪問量?

日誌片段:

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]] 
... 

回答

0

在我看來,第一個問題是您加載所有用戶要發送一個新的通知

iethis行每次:

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

然後,您將更多用戶添加到此對象,每次查找都會導致db調用以確定用戶是否已經存在。

您應該將所有用戶ID都檢索到一個散列,然後添加到該散列(如果沒有)。接下來,根據這個散列中的這些id發送你的通知。

+0

這是行不通的。調用'Notification.create(content:'',users:User.all)'仍然會驗證每個用戶。這意味着每個用戶都將驗證電子郵件的唯一性。問題不在於如何獲取'User'模型。驗證是如何被調用的 –