我对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的想法,但我仍有一些内在阻力,类似于将当前列添加到草稿表。
答案 0 :(得分: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
属性更改为“草稿”或“文档”来更新其类型。我认为这是一个比在对象上不断检查布尔值或日期属性并在应用程序中询问其状态更好的解决方案。
答案 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