2015-12-11 1 views
0

Мне нужно выполнить сложный активный запрос записи.Рельсы выполняют внутреннее соединение с активным сложным запросом записи

У меня есть 5 моделей

Card Модель

class Card < ActiveRecord::Base 
    has_many :leads 
    has_many :programs, through: :leads 
end 

Ведет Модель

class Lead < ActiveRecord::Base 
    belongs_to :card 
    belongs_to :program 
end 

Программа Модель

class Program < ActiveRecord::Base 
    has_many :leads 
    has_many :cards, through: :leads 
    belongs_to :school 
end 

Школа Модель

class School < ActiveRecord::Base 
    has_many :programs 
    belongs_to :representative 
end 

представитель Модель

class Representative < ActiveRecord::Base 
    has_many :schools 
end 

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

Я знаю, что мне нужно выполнить внутреннее соединение, но после некоторых исследований я не нашел никаких точных инструкций. Спасибо за помощь.

+0

Вам нужно создать связь между 'School' и' Card' сначала и то же самое для 'Represent'. Также я верю, что слово, которое вы ищете, является «Представитель» - «Представление» - это глагол - не существительное. – max

+0

Вы правы Я должен использовать слово представителя, но это не меняет проблемы – lonelycoder

+0

Ну где-то вдоль линии вам нужно связать карту с идентификатором школы. Как именно это зависит от моделирования домена. Может быть, 'Program'' принадлежит_to: school' – max

ответ

0

Добавление нескольких ассоциаций к некоторым из ваших моделей должно немного помочь.

class School < ActiveRecord::Base 
    # in addition to existing relations 
    has_many :leads, through: :programs 
    has_many :cards, through: :leads 
end 

class Representative < ActiveRecord::Base 
    # in addition to existing relations 
    has_many :programs, through: :schools 
    has_many :leads, through: :programs 
    has_many :cards, through: :leads 
end 

Тогда простой способ получить количество карточек, которые должна иметь простая школа или представитель, должен быть простым.

@school.cards.count 
@representative.cards.count 

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

@school.cards.distinct.count 
@representative.cards.distinct.count 

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

@schools = School.select('schools.*, count(cards.id)') 
       .joins(programs: { leads: :card }) 
       .group(:id) 

@reps = Representative.select('representative.*, count(cards.id)') 
         .joins(schools: { programs: { leads: :card } }) 
         .group(:id) 

Если вы хотите уникальный номер карты для каждой школы или представителя, просто изменить count(cards.id) к count(distinct cards.id) в соответствующем запросе.


Несколько замечаний по поводу этих решений:

  • Если школа или представитель имеет нулевой карты, они не будут появляться в в @schools и @representatives переменных. Чтобы их отобразить, вам нужно немного отрегулировать запрос и использовать LEFT JOIN.
  • Возможно, вам действительно не нужна ассоциация :cards в моделях School и Representative для получения счетов; вы могли бы, вероятно, просто использовать ассоциацию :leads.Тем не менее, это сделало бы немного сложнее, поэтому я пошел с :cards.
+0

Спасибо @Joe за ваш очень точный ответ. – lonelycoder

+0

Без проблем! Я рад помочь. –