【问题标题】:Rails has_many / has_one same modelRails has_many / has_one 同型号
【发布时间】:2011-03-03 22:56:58
【问题描述】:

所以,我有两个模型,集合和文件夹。

在每个集合中都有一个根文件夹。文件夹都属于一个集合,但也可以相互嵌套。

this question 之后,我编写了如下所示的模型。我还添加了一个回调,因为我总是希望 Collection 从根文件夹开始。

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 没有在使用关联时引发任何错误...

有什么想法吗?

【问题讨论】:

  • 您确定root_folder_id 是由setup_root_folder 方法设置的吗?我希望看到 save 来更新专栏。

标签: ruby-on-rails ruby-on-rails-3 activerecord associations


【解决方案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. 由于 C 的新 root_folder_id 没有保存,F 没有找到任何东西

如果您想对此进行测试,请在调用 f.master_collection 之前在示例代码中调用 c.save - 您应该会得到集合,正如您所期望的(您可能还需要 f.reload)。

也就是说,我从不喜欢双重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指向他们。这是你的本意吗?

【讨论】:

  • RE:master_collection 仅适用于根文件夹,这就是我的意图。仍在处理您的其余答案,谢谢!
  • @Andrew 一切都好,然后 - 只是检查。干杯!
  • 回复:has_one :root_folder .... :conditions { :parent_id =&gt; nil }。可以有多个集合,每个集合都有一个根文件夹。 ActiveRecord 怎么知道 parent_id 为 nil 的文件夹属于哪个集合?
  • @Andrew - 该声明中有一个隐含的:foreign_key =&gt; :collection_id。这是 Rails 约定的事情。同样的隐式外键让您只需调用has_many :folders - Rails 将假定属于模型MyModel 的任何东西都将使用my_model_id 来执行此操作(除非您另有说明)。
  • 哦!所以-使用现有的collection_id,其中collection_id = X AND parent_id = nil == root_folder。好的!是的,我更喜欢这种方式,而不是双重 belongs_to 方式。
猜你喜欢
  • 1970-01-01
  • 2018-04-08
  • 2012-09-18
  • 1970-01-01
  • 2019-03-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多