Has_one协会混乱,我希望它逆转

时间:2013-05-19 21:47:52

标签: ruby-on-rails activerecord has-one

我对rails非常陌生,最近我发现我理解activerecords has_one 与其实际工作方式相反。请参阅rubyonrails guide中的示例我想象供应商应该持有 account_id ,因为我认为强制每个帐户都无法容纳其供应商

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

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。

如何在rails中进行此操作?

- 更新1

为了澄清我的问题,请假设草稿 current created_at updated_at 字段无关,所以范围不会。

从表设计的角度来看,将当前字段添加到草稿表将是一个奇怪的举动。我还计划将有关已发布的草稿的信息添加到文档对象中,并将草稿表中的这些信息相乘似乎是一个奇怪的步骤

我喜欢Amesee的想法,但我仍有一些内在阻力,类似于将当前列添加到草稿表。

2 个答案:

答案 0 :(得分: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属性更改为“草稿”或“文档”来更新其类型。我认为这是一个比在对象上不断检查布尔值或日期属性并在应用程序中询问其状态更好的解决方案。

答案 1 :(得分:0)

您如何执行哪个草案是“当前”草案?它会是最近创建的吗?最后一个编辑?我希望当前的草案是草案表的逻辑计算方面,并使用范围找到它,而不是强制一个可能并不总是与逻辑匹配的固定ID。

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
相关问题