0
我有2種型號:Rails的N + 1引用相同的模型時兩次
class User < ActiveRecord::Base
end
class Message < ActiveRecord::Base
has_one :sender, :class_name => 'User'
has_one :recipient, :class_name => 'User'
end
,我想所有的用戶收到的消息,以便在messages_controller.rb
我有:
def messages_to_user
messages = Message.where(recipient_id: current_user.id)
respond_with messages
end
這項服務的工作,但在日誌中我可以看到經典的N + 1個問題:
Started GET "/messages_to_user" for 127.0.0.1 at 2017-01-22 15:35:01 +0200
Processing by MessageController#user as */*
User Load (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? ORDER BY "users"."id" ASC LIMIT 1 [["id", 2]]
Message Load (0.0ms) SELECT "messages".* FROM "messages" WHERE "messages"."recipient_id" = ? [["recipient_id", 2]]
[active_model_serializers] User Load (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1 [["id", 2]]
[active_model_serializers] CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1 [["id", 2]]
[active_model_serializers] CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1 [["id", 2]]
[active_model_serializers] CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1 [["id", 2]]
[active_model_serializers] CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1 [["id", 2]]
[active_model_serializers] CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1 [["id", 2]]
[active_model_serializers] CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1 [["id", 2]]
[active_model_serializers] CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1 [["id", 2]]
[active_model_serializers] CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1 [["id", 2]]
[active_model_serializers] CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1 [["id", 2]]
[active_model_serializers] CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1 [["id", 2]]
[active_model_serializers] CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1 [["id", 2]]
[active_model_serializers] CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1 [["id", 2]]
[active_model_serializers] CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1 [["id", 2]]
[active_model_serializers] CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1 [["id", 2]]
[active_model_serializers] CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1 [["id", 2]]
[active_model_serializers] CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1 [["id", 2]]
[active_model_serializers] CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1 [["id", 2]]
[active_model_serializers] Rendered ActiveModel::Serializer::CollectionSerializer with ActiveModelSerializers::Adapter::Attributes (42.01ms)
Completed 200 OK in 217ms (Views: 63.0ms | ActiveRecord: 3.0ms)
所以,我想通過增加,以解決它:
def messages_to_user
messages = Message.includes(:recipient).where(recipient_id: current_user.id)
respond_with messages
end
但後來我得到以下錯誤:
SQLite3::SQLException: no such column: users.message_id: SELECT "users".* FROM "users" WHERE "users"."message_id" IN ('1', '2', '3', '4', '5', '6', '7', '8', '9')
如何可以解決嗎? 我想返回一組消息 - 不是用戶和用戶內部設置的消息。但沒有N + 1問題
EDIT
2個模型之間的連接是通過郵件表完成的,這裏是遷移(字段發件人,收件人),所以我不需要的users.message_id
在users
。此外,任何用戶都可以發送/接收多條消息,也許我的實現不反映?應該怎麼做?
這裏是消息遷移:
class CreateMessages < ActiveRecord::Migration
def change
create_table :messasges do |t|
t.string :title
t.references :sender, index: true, foreign_key: true
t.references :recipient, index: true, foreign_key: true
t.string :content
t.timestamps null: false
end
end
end
那麼,你必須添加所需的列,該錯誤信息是很清楚,存在丟失的'message_id'列上用戶表。 – Iceman
@Iceman請看我的編輯,thatnks。 – yossico
我可以看到,錯誤消息說,這個列在用戶表中丟失,但sinc用戶可以有很多消息,我不能把message_it列放在那裏。正確的方法是在消息表中添加user_it,然後再次如何防止n + 1? – yossico