Недопустимый макрос отражения источника: has_many: through - PullRequest
2 голосов
/ 18 декабря 2009

У меня есть такие злые ассоциации: финансы> - события> - подпрограммы> - программы. Я хочу получить доступ к last_financings из программ через все из них, поэтому код:

class Fcp < Program
  has_many :fcp_subprograms,
           :foreign_key => 'parent_id'
  has_many :subprogram_last_actual_financings,
           :through => :fcp_subprograms,
           :source => :last_actual_financings

class FcpSubprogram < Program
  belongs_to :fcp,
             :class_name => 'Fcp',
             :foreign_key => 'parent_id'

  has_many :events,
           :foreign_key => 'fcp_id'

  has_many :last_actual_financings,
           :through => :events,
           :source => :last_actual_financings

class Event < ActiveRecord::Base
  belongs_to :fcp,
             :class_name => 'Fcp',
             :foreign_key => 'fcp_id'
  belongs_to :fcp_subprogram,
             :class_name => 'FcpSubprogram',
             :foreign_key => 'fcp_id'

  has_many :last_actual_financings,
           :class_name => 'ActualFinancing',
           :order => 'date DESC',
           :limit => 1

Поэтому, когда я хочу получить доступ к subprogram_last_actual_financings в функции after_initialize, я получаю эту ошибку

Invalid source reflection macro :has_many :through for has_many :subprogram_last_actual_financings, :through => :fcp_subprograms.  Use :source to specify the source reflection.

но у меня есть: опция источника в моих ассоциациях. Что я делаю не так?

Ответы [ 3 ]

6 голосов
/ 21 декабря 2009

Ошибка, которую вы получите о source_reflection, является недопустимой ассоциацией, потому что источник для сквозного has_many должен быть принадлежат__, has_one или has_many без сквозного параметра.Поэтому вы не можете использовать: last_actual_financings в качестве источника.

3 голосов
/ 21 декабря 2009

Насколько я помню, вы не можете объединиться с двойным (или более): через. Единственное, что вы можете сделать, это написать свои собственные SQL-запросы.

Вот мой пример, как это сделать:

class Person
  ...
  has_many :teams, :finder_sql =>
    'SELECT DISTINCT teams.* FROM teams
        INNER JOIN team_roles ON teams.id = team_roles.team_id
        INNER JOIN team_members ON team_roles.id = team_members.role_id
        WHERE ((team_members.person_id = #{id}))'

  # other standard associations
  has_many :team_members
  has_many :team_roles,
    :through => :team_members
  # and I couldn't do:
  # has_many :teams, :through => :team_roles

Это для отношения Person -> has_many -> team_members -> has_many -> team_roles -> has_one - team.

Надеюсь, это поможет.

0 голосов
/ 18 декабря 2009

Это кажется очень неудобным способом сделать это ... Я бы предпочел сделать виртуальный метод доступа в Program, который вызывает что-то вроде этого:

self.subprograms.first.events.first.financings.first(:order => 'date DESC')
...