ruby-on-rails – MiniProfiler列出的额外查询

在我的控制器操作中,我包含了视图所需的所有关联,以避免多次调用数据库. (我试图将视图层隔离为仅渲染控制器收集的数据).

I’v found out that the view still communicates with the database (17 Queries):

不需要这17个额外查询.因为我已经从控制台测试了控制器查询,并且它成功地收集了部分_dropdown(在5个查询中)所需的所有数据,而没有任何进一步的数据库通信.

这是我的控制器中的query,它是为了避免N 1问题. (包括视图中调用的所有变量)

这是下拉代码

- @messages.each do |message|
    %li.conversation-container
        %a{href: conversation_path(message.conversation_id)}
            - if message.sender != current_user 
                .notification-avatar{style: "background: url(#{message.sender.avatar_url}); background-size: contain; background-repeat: no-repeat; background-position: 50% 50%;"}
            - else
                - other_participant = message.conversation.conversation_participants.select{|p| p.user_id != current_user.id }.first.user 
                .notification-avatar{style: "background: url(#{other_participant.avatar_url}); background-size: contain; background-repeat: no-repeat; background-position: 50% 50%;"}
            %p
                %strong
                    - if message.sender != current_user 
                        = message.sender.name
                    - else
                        = other_participant.name
                %br
                - if message.sender == current_user
                    %i.fa.fa-mail-reply-all
                = truncate(message.body,length: 25)

                .time
                    = time_ago_in_words(message.created_at)
                    ago
- if @messages.count == 0
    %li
        .empty-state-text-white
            No messages

控制台输出

2.0.0-p353 :006 > ms = Message.dropdown_for(3).all
  Message Load (1.2ms)  SELECT "messages".* FROM "messages" LEFT JOIN messages AS m ON messages.id != m.id 
 AND m.conversation_id = messages.conversation_id 
 AND messages.created_at < m.created_at INNER JOIN conversation_participants AS cp ON cp.conversation_id = messages.conversation_id AND cp.user_id = 3 WHERE (m.id IS NULL) ORDER BY cp.seen,cp.updated_at DESC LIMIT 5
  User Load (0.7ms)  SELECT "users".* FROM "users" WHERE "users"."id" IN (6,4,5)
  Conversation Load (0.4ms)  SELECT "conversations".* FROM "conversations" WHERE "conversations"."id" IN (4,2,3)
  ConversationParticipant Load (0.2ms)  SELECT "conversation_participants".* FROM "conversation_participants" WHERE "conversation_participants"."conversation_id" IN (4,3)
  User Load (0.6ms)  SELECT "users".* FROM "users" WHERE "users"."id" IN (6,3,5)
 => [#<Message id: 8,body: "saSasa",sender_id: 6,conversation_id: 4,sent: true,attachment_id: nil,attachment_type: nil,created_at: "2014-11-17 16:05:40",updated_at: "2014-11-17 16:05:40">,#<Message id: 2,body: "asdnas dagsdashjdg jahs d",sender_id: 4,conversation_id: 2,created_at: "2014-11-17 11:32:36",updated_at: "2014-11-17 11:32:36">,#<Message id: 6,body: "SADASD A DSA ",sender_id: 5,conversation_id: 3,created_at: "2014-11-17 13:43:34",updated_at: "2014-11-17 13:43:34">] 

2.0.0-p353 :007 > ms.first.conversation.conversation_participants.select{|cp| cp.user_id != 3}.first.user
 => #<User id: 6,first_name: "Ddsfsd",middle_name: nil,last_name: "Fsdfsd",photo: nil,email: "1@k.com",encrypted_password: "$2a$10$5sgib2DbQ1ctMrTzD3AJ0uV18hhiC5Ei1wcfE7MSAvRU...",reset_password_token: nil,reset_password_sent_at: nil,remember_created_at: nil,sign_in_count: 1,current_sign_in_at: "2014-11-17 15:27:06",last_sign_in_at: "2014-11-17 15:27:06",current_sign_in_ip: "127.0.0.1",last_sign_in_ip: "127.0.0.1",confirmation_token: nil,confirmed_at: "2014-11-17 15:27:48",confirmation_sent_at: "2014-11-17 15:27:05",unconfirmed_email: nil,Failed_attempts: 0,unlock_token: nil,locked_at: nil,authentication_token: nil,created_at: "2014-11-17 15:27:05",updated_at: "2014-11-17 15:27:48",slug: "ddsfsd_fsdfsd"> 

2.0.0-p353 :008 > ms.count
 => 3

如何在没有目的的情况下阻止这些查询运行?

解决方法

*调试

在调试可能导致此问题的每个可能因素之后.
我试着在我的development.rb中将config.cache_classes设置为true.这成功删除了所有额外的查询.

我得出结论(认情况下)在未缓存类时,不会为任何模型加载模式.换句话说,当config.cache_classes设置为false时,将为每个请求加载每个模型的模式作为单独的查询.

这是一个类似的问题column_definitions method being called before and after every single SQL statement on PostgreSQL.

*结论

cache_classes should be set to false in development environment.
Ignore the extra internal queries from postgresql connection adapter
loading the schema for each model since it not going to affect your
production environment (production has config.cache_classes set to
true).

相关文章

validates:conclusion,:presence=>true,:inclusion=>{...
一、redis集群搭建redis3.0以前,提供了Sentinel工具来监控各...
分享一下我老师大神的人工智能教程。零基础!通俗易懂!风趣...
上一篇博文 ruby传参之引用类型 里边定义了一个方法名 mo...
一编程与编程语言 什么是编程语言? 能够被计算机所识别的表...
Ruby类和对象Ruby是一种完美的面向对象编程语言。面向对象编...