Rails стремится загрузить custom has_many в индекс - PullRequest
0 голосов
/ 03 мая 2018

Ruby 2.1, Rails 3.2
У меня есть эти отношения в моей модели проекта

scope :active, -> { where( deleted_at: nil ) }
has_many :foremen, class_name: "ProjectsUser",  conditions: ['current_foreman = 1']

в контроллере:

@projects = Project.includes(:foremen).active

, который генерирует этот SQL

ProjectsUser Load (3.3ms)  SELECT `projects_users`.* FROM `projects_users` WHERE `projects_users`.`project_id` IN (122, 130, ...etc.) AND ( current_foreman = 1)

но когда я называю отношения в представлении ...

<% @projects.each do |project| %>
  <%= project.foremen.current_foreman %>
<% end %> 

каждый раз запускается другой SQL-запрос.

ProjectsUser Load (2.5ms)  SELECT `projects_users`.* FROM `projects_users` WHERE `projects_users`.`project_id` = 122 AND (current_foreman = 1 )
ProjectsUser Load (2.5ms)  SELECT `projects_users`.* FROM `projects_users` WHERE `projects_users`.`project_id` = 130 AND (current_foreman = 1 )
ProjectsUser Load (2.5ms)  SELECT `projects_users`.* FROM `projects_users` WHERE `projects_users`.`project_id` = 151 AND (current_foreman = 1 )
etc...

я что-то неправильно понимаю? не должны ли эти записи уже быть загружены?
как мне написать это, чтобы он выполнял только один запрос для ProjectsUser?

Ответы [ 2 ]

0 голосов
/ 07 мая 2018

так что я немного покопался и обнаружил, что моя логика была правильной; это не генерирует никаких дополнительных запросов само по себе. проблема была в методе, который я вызывал для объекта.

следующие запросы не вызывают:

 project.current_foremen_and_managers.select{|f| f.current_foreman}.sort_by{ |f| f.added_at}.first

однако, когда вы перемещаете дополнительную логику в метод в связанном классе, он генерирует больше sql

class ProjectUser < ActiveRecord::Base
  def self.find_first_foreman
    select{|f| f.current_foreman}.sort_by{ |f| f.added_at}.first
  end
end

тогда, если я вызову этот метод, он выполнит запрос

project.current_foremen_and_managers.find_first_foreman

Я не совсем уверен, почему это происходит, если у кого-нибудь есть объяснение, которое я хотел бы услышать.

0 голосов
/ 03 мая 2018

Я думаю, это нормально, вы называете это внутри цикла проектов.

...