2013-05-19 65 views
0

我很新的轨道和最近我发现,我明白activerecords has_one协会相反,它如何实际工作。参考rubyonrails guide的例子,我想到供应商应该持有它的account_id,因为我没有意见强迫每个账户持有它的供应商。Has_one协会混淆,我想它颠倒

因为我真的不明白为什么,或者根本不同意维护它的外键在其他对象中的对象,我不知道什么是我的简单问题的正确轨道解决方案: 我有两个对象 - 文档草稿。每份文件都有很多草稿,其中一份标记为当前草稿。我想象中的表格布局是这样的:

table document 
    id 
    current_draft_id 
table draft 
    id 
    document_id 
    text 

我正在寻找在这里有点像一个HAS_ONE联系,但逆转,因此,该文件将保持和维护current_draft_id。使用belongs_to不是一种选择,因为它的行为不同。例如,我想document.current_draft = new_draft正确地更新foreign_key。

如何解决这个在轨道?

- 更新1

为了澄清我的问题,请假设是草案当前不会有无关created_at的updated_at领域,所以范围不会做。

添加当前场到草案表是从视表的设计点一个奇怪的举动。我还打算将已发布的草稿的信息添加到文档对象中,并将这些信息与草稿相乘,这似乎是一个奇怪的步骤。

我喜欢Amesee的想法,但我仍然有一些内部阻力,类似于加入当前列到草案表。

回答

0

你如何执行哪个草稿是“当前”草稿?它会是最近创建的吗?最后一个编辑?我希望当前的草案是草稿表的一个逻辑计算方面,并用范围来发现它,而不是强制一个固定的标识符,这个标识符可能并不总是符合逻辑。

class Document < ActiveRecord::Base 
    has_many :drafts 

    def current_draft 
    self.drafts.ordered.first 
    end 
end 

class Draft < ActiveRecord::Base 
    belongs_to :document 

    scope :all 
    scope :ordered, order_by(:updated_at) 
end 

或者,:current, :boolean, :default => false字段添加到草稿表,并有有只有一个与当前的是真实的孩子。(此方法的逻辑的一个很好的解释可以在这里找到:Rails 3 app model how ensure only one boolean field set to true at a time

如果你真的希望有父固定子ID,那么你需要用一个定义外键:belongs_to

文件表:

id 
current_draft_id 

型号:

class Document < ActiveRecord::Base 
    has_many :drafts 
    belongs_to :current_draft, :class_name => 'Draft', :foreign_key => 'current_draft_id' 
end 

控制器代码的地方:

@document.current_draft = @draft 
+0

感谢马特,请参阅我的问题的*更新1 *。我还谈到了与我想实现的不同的* belongs * _to *关联。 – majkel

+0

我的最终建议与你想要做的精确匹配,你添加了原始文章中的字段,通过'.current_draft'调用它,我不明白为什么它不适合你?编辑:我已经澄清了一下。 – Matt

+0

看看[文档](http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html),并找到它是属于\ _to还是\ _one关联?_段。 _belongs \ _to_ association假定在我们的例子中它将是_draft_对象,它将负责维护它在* document *对象中的键。因此'@document.current_draft = @ draft'不会更新文档对象。 – majkel

1

我认为DraftDocument因此它可能更有意义来管理这些类单表继承。您可以通过其类型来了解草稿是“当前草稿”。

class CreateDocuments < ActiveRecord::Migration 
    def change 
    create_table :documents do |t| 
     t.string :type 
     # ... 

     t.timestamps 
    end 
    end 
end 

和模型。

class Document < ActiveRecord::Base 
    # ... 
end 

class Draft < Document 
    # ... 
end 

class CurrentDraft < Draft 
    # ... 
end 

后来,当不是选秀“当前”了,通过改变其type属性为“草稿”或更新型“的文件。”我认为这是一个比不断检查对象的布尔或日期属性并在应用程序中查询其状态的更好解决方案。

+0

你有一个有效的点,我会考虑它。但我仍然认为从表格布局的角度来看,我的计划最终会更容易维护。 – majkel

+0

第二个想法是,如果我希望草稿共享像文档对象中的标题一样的字段? – majkel

+0

所有这些类共享相同的基础表,因此它们已经共享相同的一组属性(技术上它们都具有相同的属性访问器方法)。唯一的区别是根据'type'的值实例化的对象的基础类型。 – veidt