0

我对 Rails 很陌生,最近我发现我理解 activerecords has_one关联与它的实际工作方式相反。参考 ruby ​​onrails guide中的示例,我认为应该是供应商持有其account_id,因为我认为强制每个账户持有其供应商是没有意义的。

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

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

为了澄清我的问题,请假设当前的草稿与created_atupdated_at字段无关,因此范围不会这样做。

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

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

4

2 回答 2

1

我认为这Draft是一个Document,因此使用单表继承来管理这些类可能更有意义。您可以根据其类型判断草稿是“当前草稿”。

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

于 2013-05-19T23:57:05.487 回答
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 一次

如果你真的想在父节点中有一个固定的子 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
于 2013-05-19T23:47:03.927 回答