0

N + 1 обнаружено, что это значит, что я должен сделать, чтобы заставить его работать.Уменьшить N + 1 Запросы

Я использую Пули камень для показа N + 1 запросов

user: kalyan 
N+1 Query detected 
    Emp => [:functions] 
    Add to your finder: :include => [:functions] 
N+1 Query method call stack 
    /home/Documents/app/views/tics/show.html.haml:20:in `_app_views_tics_show_html_haml___2301551533476719406_237290860' 

Это сообщение от пули камень.

_app_views_tics_show.html.haml

- if (@tic.assigned_to == current_user.emp) or (current_user.emp_functions.map{|x| x.id}.include?(1) if current_user.emp_functions.present?) 
       = best_in_place @tic, :subject 
      - else 
       = @tic.subject 

помочь мне уменьшить проблему п + 1 запрос

emp.rb

has_many :emp_functions, inverse_of: :emp,dependent: :restrict_with_exception 

belongs_to: пользователь, inverse_of:: emp

emp_functions.rb

belongs_to :emp , inverse_of: :emp_functions 

belongs_to :function 

function.rb

has_many :emp_functions, dependent: :restrict_with_exception 

has_many :emp, through: :emp_functions 

user.rb

has_one :emp, inverse_of: :user, dependent: :restrict_with_exception 
+0

sem-related - http://stackoverflow.com/a/26251892/525478 –

ответ

1

Имхо, самый эффективный способ избавиться от N + 1 запрос является изменение метода current_user, добавляя includes(:emp_functions) к User.find вызова. То, как вы это делаете, зависит от способа аутентификации. Если вы используете какой-то драгоценный камень (например, Devise или Sorcery), вам нужно будет снова открыть эти классы и изменить метод, не забывая использовать super. Если вы написали свою собственную аутентификацию, вы сможете сделать это более легко.

Вторая вещь, которую я заметил, что вы на самом деле не нужно использовать map на вашем user.emp_functions в представлении, при условии, что emp_functions является has_many ассоциация по User модели. Вы можете просто сгладить его до current_user.emp_function_ids.include?(1). Это поможет вам избавиться от проблемы с запросом N + 1, но только в этом конкретном случае. Если вы часто занимаетесь emp_functions текущего пользователя во многих местах, я бы рекомендовал использовать первый описанный мной путь.

Третья вещь, не имеющая прямого отношения к вопросу, состоит в том, что я действительно не думаю, что этот код принадлежит ко взгляду. Вы должны перенести его в помощника или декоратора, сохраняя представление чистым и читаемым.

+1

плюс 1 для третьей вещи –

+0

NoMethodError: неопределенный метод 'emp_function_ids 'для # <Пользователь: 0x00000012819f68> из /home/.rvm/gems/[email protected]/gems/activemodel-4.2.0/lib/active_model /attribute_methods.rb:433:in 'method_missing ' – sreenivas

+0

Пожалуйста, проверьте Код модели – sreenivas

0

Если emp_functions является has_many ассоциации на вашей модели пользователя (и похоже, что это так), вы должны быть doi нг:

current_user.emp_function_ids.include?(1) 
+0

Я думаю, что лучше отредактировать метод current_user, поэтому вы не будете решать emp_functions каждый раз, когда вам нужно найти пользователя или получить список пользователей. В памяти может быть много данных. – Almaron

0

Это очень конкретное решение вашей проблемы, и я советую использовать ее в целях

изменения current_user.emp_functions.map{|x| x.id}.include?(1) в

current_user.emp_functions.where(id: 1).exists? 

Это приведет к 1 одного запроса к БД каждый раз вы попали в содержащую его.

Вы также можете удалить оператор if, чтобы удалить другой запрос db.

+0

не работал, не могли бы вы изменить его по-другому. то, что я имею в виду, было на самом деле тем запросом, который вы дали мне, чтобы получить надлежащую запись, но все же N + 1 Query Problem. – sreenivas

+0

, тогда проблема с запросом N + 1 происходит где-то в другом месте. – jvnill

Смежные вопросы