Has_one关联混淆,我希望它颠倒



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

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

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中实现这一点?

update 1

为了澄清我的问题,请假设草案是当前将不会与created_atupdated_at字段无关,所以作用域不会做。

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

我喜欢Amesee的想法,但我仍然有一些内在的阻力,类似于在drafts表中添加current列。

我认为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属性更改为"draft"或"Document"来更新其类型。我认为这是一个更好的解决方案,而不是不断检查对象上的布尔或日期属性,并询问其在应用程序中的任何地方的状态。

如何强制执行哪个草案是"当前"草案?它会是最近创建的吗?最后编辑的那个?我将使当前的草案是草案表的逻辑计算的方面,并找到它的范围,而不是强制一个固定的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字段添加到草稿表中,并且只有一个current为true的子字段。(这个方法的逻辑可以在这里找到一个很好的解释:Rails 3应用程序模型如何确保一次只有一个布尔字段设置为真)

如果您真的想要在父元素中有一个固定的子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

相关内容

  • 没有找到相关文章

最新更新