Rails имеет много / имеет одну и ту же модель


Итак, у меня есть две модели, коллекция и папка.

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

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

class Folder < ActiveRecord::Base
  has_one :master_collection, :class_name => 'Collection', :foreign_key => :root_folder_id
  belongs_to :collection
  belongs_to :parent, :class_name => 'Folder'
  has_many :subfolders, :class_name => 'Folder', :foreign_key => :parent_id
  ...
end

class Collection < ActiveRecord::Base
  belongs_to :root_folder, :class_name => 'Folder'
  has_many :folders

  after_create :setup_root_folder

  private
  def setup_root_folder
    self.root_folder = Folder.create(:name => 'Collection Root', :collection => self )
  end
end

В папках у меня есть столбцы: parent_id, folder_id В коллекциях у меня есть колонка: root_folder_id

Похоже, что это должно сработать, но я получаю это странное поведение в консоли:

ruby-1.9.2-p0 :001 > c = Collection.create(:name=>"Example")
 => #<Collection id: 6, name: "Example", ...timestamps..., root_folder_id: 8> 
ruby-1.9.2-p0 :003 > f = c.root_folder
 => #<Folder id: 8, parent_id: nil, name: "Collection Root", ...timestamps..., collection_id: 6> 
ruby-1.9.2-p0 :004 > f.master_collection
 => nil 

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

Есть идеи?

1 2

1 ответ:

Я подозреваю, что именно это и происходит:

  1. вы создаете коллекцию C
  2. C сохраняется в базе данных
  3. Rails вызывает C.after_create
  4. вы создаете папку F
  5. F сохраняется в базе данных
  6. C root_folder_id устанавливается в F id
  7. это изменение не сохраняется в базе данных
  8. вы звоните F.master_collection
  9. F запрашивает базу данных, ищет коллекции с помощью coleections.root_folder_id = folders.id
  10. поскольку новый root_folder_id C не был сохранен, F не находит ничего

Если вы хотите проверить это, вызовите c.save в своем примере кода перед вызовом f.master_collection - и вы должны получить коллекцию, как вы ожидаете (вам может понадобиться f.reload тоже).

Тем не менее, мне никогда не нравился double belongs_tos (папка принадлежит коллекции + коллекция принадлежит корневой папке). Вместо этого я бы рекомендовал:

class Collection < ActiveRecord::Base
    has_one :root_folder, :class_name => 'Folder', :conditions => {:parent_id => nil}

    # ...other stuff...
end

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

PS: ваше определение Folder.master_collection вернет вам коллекцию, только если вы назовете ее из корневой папки-все остальные папки просто вернут nil, так как никакие коллекции не имеют root_folder_idS, которые указывают на них. Вы это имели в виду?