代码之家  ›  专栏  ›  技术社区  ›  Olivier Tremblay

更友好的ROR活动记录模型定义?

  •  1
  • Olivier Tremblay  · 技术社区  · 14 年前

    关于轨道的简单问题:

    是否可以从模型RB文件中描述模型的结构?

    据我所知,模型的数据结构保存在迁移中,model.rb文件应该只包含业务逻辑。

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

    2 回复  |  直到 14 年前
        1
  •  2
  •   cam    14 年前

    迁移是单独存储的,因此您可以对数据库进行版本控制。如果在模型中以内联方式进行,这将是非常不方便的。

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

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

        2
  •  1
  •   Legion    14 年前

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

    他们定义了 转变 从一个州到另一个州。

    在对cam文章的评论中,你说在模型中使用模式也会做同样的事情,如果你将模型的源代码存储在VCS中,你可以查找模式的早期版本。

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

    架构版本1
    字符串:名称
    字符串:密码
    字符串:令牌

    架构版本2
    字符串:用户名
    字符串:显示名称
    字符串:密码
    字符串:令牌

    那么,我在这里做了什么?“名字”怎么了?我把它重命名为用户名了吗?或者我把它改名为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中给出了一个小例子。无论您需要执行什么代码来将数据迁移到新的模式,您都可以放入迁移中。

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