Friendlier RoR ActiveRecord模型定义?

时间:2010-08-16 20:58:14

标签: ruby-on-rails activerecord

过去常常让我困惑Rails的简单问题:

是否可以在模型rb文件中描述模型的结构?

根据我的理解,模型的数据结构保留在迁移中,而model.rb文件应该只包含业务逻辑。

为什么会这样?为什么使用rake任务迁移数据库比从类中提取数据更有意义?

2 个答案:

答案 0 :(得分:2)

迁移单独存储的原因是您可以对数据库进行版本控制。如果在模型中内联完成,这将是不实用的。

其他ORM(如DataMapper)会将模式存储在模型定义中。我认为能够在那里看到模型属性非常方便,但不幸的是没有数据库结构的历史。

我真正希望运行迁移只是在详细说明架构的模型文件的顶部插入一些注释。那应该是一个简单的黑客攻击。

答案 1 :(得分:1)

迁移不仅仅显示数据库模式的状态。

他们将过渡从一种状态定义为另一种状态。

在对post的帖子的评论中,你说模型中的模式会做同样的事情,如果模型的源存储在VCS中,你可以查找模式的先前版本。

这就是为什么它不等同于迁移:

架构版本1
string:name
string:密码
string:token

架构版本2
string:username
string:displayname
string:密码
string:token

那么,我在这做了什么? “名字”怎么了?我是否将其重命名为用户名?或者我可能将其重命名为displayname?或者我完全放弃了它?

你不知道。没有办法说出来。您只能看到架构的“之前”和“之后”。你没有看到过渡。

让我们看一下我对这次迁移的真正做法:

class UpdateNameFields < ActiveRecord::Migration
  def self.up
    rename_column :users, :name, :username
    add_column :users, :displayname
    User.update_all("displayname = username")
  end

  def self.down
    remove_column :users, :displayname
    rename_column :users, :username, :name
  end
end

请参阅,我一直在使用“name”作为用户名。但如果没有这里的迁移,你将无法说出来。另外,为了不让我的新displayname列在我现有的所有记录中都是空白的,我已将其与每个人的现有用户名一起播种。这让我可以轻轻地介绍这个新功能 - 我可以使用它,并且知道现有记录不会只看到空白字段。

请注意,这是琐碎的示例。因为它是如此微不足道,你可以猜测它是几种可能的选择之一。但如果这是一个更加复杂的过渡,你根本就不会知道。

从一个架构到另一个架构的转换可能不仅仅涉及添加/删除/重命名列。我在User.update_all中给出了一个小例子。无论您将数据迁移到新架构可能需要执行什么代码,都可以进行迁移。

当人们说迁移是关于“版本化数据库”时,它们并不仅仅意味着对模式的快照进行版本控制。它们意味着能够在这些模式状态之间移动,并触发从一个状态转到另一个状态所涉及的所有操作。