Комплекс Rails has_many и has_many через

У меня есть 4 модели: Drawer, Folder, FolderDocument и Document следующим образом:

class Drawer < ActiveRecord::Base
  has_many :folders #Drawer has many folders
end

class Folder < ActiveRecord::Base
  belongs_to :drawer
  has_many :folder_documents

  # Folder has a "version" attribute which reflects the latest version
  # Use proc to give back latest version by default e.g. folder.documents or folder.documents(5) will give back a specific version.      
  has_many :documents, :through => :folder_documents, :conditions => proc { |v = nil|
         v ||= self.version
         "documents.active IS TRUE AND version = #{v}"
       }, :uniq => true 
end

class FolderDocument < ActiveRecord::Base
  # Has a version attribute
  belongs_to :document
  belongs_to :folder
end

class Document < ActiveRecord::Base
  has_many :folder_documents
  has_many :folders, :through => :folder_documents
end

Моя проблема в том, что я не могу создать

has_many :documents, :through => :folders

в классе Drawer, так как условия процедуры (для документов из FolderDocument) не могут быть рассчитаны, поскольку «версия» рассчитывается в контексте Drawer, а не промежуточной ассоциации папок.

Есть ли способ сделать это без создания другой модели между Folder и FolderDocuments, называемой FolderVersion?

РЕДАКТИРОВАТЬ: Цель состоит в том, чтобы получить все документы, принадлежащие папке для текущей версии (версии в папках).


person ankimal    schedule 20.02.2013    source источник
comment
Мне кажется, у вас тут опечатки has_many :drawers #Drawer has many folders   -  person Firyn    schedule 21.02.2013
comment
Фиксированный. Спасибо за это.   -  person ankimal    schedule 21.02.2013
comment
Не могли бы вы объяснить немного яснее, чего вы пытаетесь достичь? Там может быть какое-то совсем другое решение. :-D   -  person Thomas Klemm    schedule 21.02.2013
comment
Я пытаюсь найти ВСЕ документы, принадлежащие папке для самой последней версии.   -  person ankimal    schedule 21.02.2013
comment
Похожие вопросы: stackoverflow.com/q/7753162/178651 и stackoverflow.com/q/5856838/178651   -  person Gary S. Weaver    schedule 21.02.2013
comment
@GaryS.Weaver: Как мне добавить что-то к условию соединения, если я добавлю область к has_many?   -  person ankimal    schedule 21.02.2013
comment
@ankimal Итак, если folder.documents, то folders.version = folders_documents.version и document.active истинно, но если folder.documents(x), то условие будет проверять, что folders_documents.version равно x, а document.active истинно?   -  person Gary S. Weaver    schedule 21.02.2013
comment
Извините, я имел в виду folder_documents как имя таблицы (случайно подумал об имени таблицы habtm по умолчанию). Не сработает ли просто изменить условие выше на documents.active IS TRUE AND folder_documents.version = #{v}? Вы также можете использовать область действия в модели присоединения или делать такие вещи, как передача блока в has_many, чтобы переопределить методы ассоциации (например, <<(some_var) и т. д., как указано в ответах на вопросы, на которые я ссылался.   -  person Gary S. Weaver    schedule 21.02.2013
comment
@GaryS.Weaver Проблема с условиями proc заключается в том, что они оцениваются в рамках вызывающего класса. Для Folder.first.documents и Folder.first.documents(2) отлично работает. Но Drawer.documents терпит неудачу, так как #{v} оценивается в контексте ящика, а не папки.   -  person ankimal    schedule 21.02.2013
comment
@ankimal Drawer не имеет ассоциации документов в указанном вами коде модели. Кроме того, это не тот вопрос, который вы задали, вы сказали РЕДАКТИРОВАТЬ: Цель состоит в том, чтобы получить все документы, принадлежащие папке для текущей версии (версия в папках). но это не то, что вы только что сказали, поскольку, по-видимому, получение доступа к документам из Drawer также является тем, что вы ищете?   -  person Gary S. Weaver    schedule 21.02.2013
comment
Если вы уже просмотрели предыдущие ссылки, которые я упомянул, взгляните также на stackoverflow.com/q/2462203/178651 и stackoverflow.com/a/4632472/178651. Но я думаю, что если бы вы указали имя таблицы во фрагменте SQL условия, как я упоминал в предыдущем комментарии (folder_documents.version = #{v} против version = #{v}), вы могли бы просто использовать аналогичную ассоциацию и процедуру в любом классе, который вам нужен (просто изменив имена таблиц и т. д. по мере необходимости).   -  person Gary S. Weaver    schedule 21.02.2013
comment
Кроме того, убедитесь, что v правильно очищен, чтобы избежать SQL-инъекций.   -  person Gary S. Weaver    schedule 21.02.2013