`
jiajie0531
  • 浏览: 29538 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

Rails Database Migrations 6 Using Models in Your Migrations 在你的数据迁移中使用模型

阅读更多

version: Rails 4.1

当在一个数据迁移文件(migration)里创建或者修改数据时, 通常比较吸引人的做法是使用你的模型中的一个. 毕竟, 他们的存在是为了提供更便捷的读取那些潜在的数据. 这是能够实现的, 但有些警告应该要被注意到.
 
例如, 问题的产生是在模型使用数据列时,1)这些数据列没有存在于数据库中 2)将会被这个或者随后的 migration 来创建。
 
考虑这个例子,Alice 和 Bob 共同工作于同一个代码,包含一个 Product 模型:
 
Bob 度假去了。
 
Alice 创建了一个 数据迁移文件(migration) 服务于 products 数据表,增加了一个新的列,然后初始化它:

# db/migrate/20100513121110_add_flag_to_product.rb
 
class AddFlagToProduct < ActiveRecord::Migration
  def change
    add_column :products, :flag, :boolean
    reversible do |dir|
      dir.up { Product.update_all flag: false }
    end
  end
end

她同样地也给 Product的一个新的列 增加了一个验证:


# app/models/product.rb
 
class Product < ActiveRecord::Base
  validates :flag, inclusion: { in: [true, false] }
end

Alice 增加第二个 migration,用来在 products 数据表中增加另一个列,然后再初始化它:


# db/migrate/20100515121110_add_fuzz_to_product.rb
 
class AddFuzzToProduct < ActiveRecord::Migration
  def change
    add_column :products, :fuzz, :string
    reversible do |dir|
      dir.up { Product.update_all fuzz: 'fuzzy' }
    end
  end
end

她同样地也对于 Product 模型的一个新的列增加了一个验证:


# app/models/product.rb
 
class Product < ActiveRecord::Base
  validates :flag, inclusion: { in: [true, false] }
  validates :fuzz, presence: true
end

两个 migrations 都是为 Alice 工作的。

Bob 从假期中回来了:

  • 更新了代码—— 这其中包含了两个 migrations 和最近版本的 Product 模型。
  • 运行未被执行过的 migrations 用 rake db:migrate,包括那个 Product 模型的更新。

migration 有冲突了,因为当模型想要保存的时候,尝试着去验证第二个新增的列,当第一个 migration 运行的时候,这一列是不存在与数据库中的:


rake aborted!
An error has occurred, this and all later migrations canceled:
 
undefined method `fuzz' for #<Product:0x000001049b14a0>

一个解决的办法就是,在一个 migration 中创建一个本地模型。这使得让 Rails 持续地执行验证,因此 migrations 可以完整的运行了。

当使用一个本地模型时,比较好的做法是调用 Product.reset_column_information 来刷新 Active Record 的缓存,为了 Product 模型在数据库中优先更新数据。

如果 Alice 已经这样做了,那就不会存在问题了:

# db/migrate/20100513121110_add_flag_to_product.rb
 
class AddFlagToProduct < ActiveRecord::Migration
  class Product < ActiveRecord::Base
  end
 
  def change
    add_column :products, :flag, :boolean
    Product.reset_column_information
    reversible do |dir|
      dir.up { Product.update_all flag: false }
    end
  end
end
# db/migrate/20100515121110_add_fuzz_to_product.rb
 
class AddFuzzToProduct < ActiveRecord::Migration
  class Product < ActiveRecord::Base
  end
 
  def change
    add_column :products, :fuzz, :string
    Product.reset_column_information
    reversible do |dir|
      dir.up { Product.update_all fuzz: 'fuzzy' }
    end
  end
end

在上面的例子中,可能还有其他的错误。

 

例如,想象一下,Alice 创建了一个 migration ,有选择地更新某些 products 的 description 字段。她运行 migration,提交代码,然后开始工作于下一个任务,在 products 数据表中增加一个新的列。

 

对于这个新的任务,她创建了两个 migrations,一方面是增加了新的列,另一方面是有选择地更新 fuzz 列,基于 product 的其他特性。

 

这些 migrations 可以很好地执行,但当 Bob 从他的假期中归来,调用 rake db:migrate 去运行所有未执行过的 migrations,他得到了一个不可思议的 bug :description 字段中有默认值,fuzz 列是显示的,但 所有的products中 fuzz 的值是nil。

 
解决的办法是再一次使用 Product.reset_column_information, 位于一个 migration 里引用 Product 模型之前。在操作那些记录数据之前,确保 Active Record 能了解当前其数据表结构。
 

 

0
0
分享到:
评论

相关推荐

    mongoid_rails_migrations, Mongoid的数据迁移.zip

    mongoid_rails_migrations, Mongoid的数据迁移 发行说明最新版本,1.1. x, 目标 Mongoid&gt; = 4.0.0和 Rails&gt; = 4.2.0.对于 Rails&gt; = 3.2.0和 Mongoid&gt; = 3.0.0,使用版本 1.0.0.

    mongoid_rails_migrations:Mongoid的数据迁移

    Mongoid的数据迁移。 宝石文件: gem "mongoid_rails_migrations" 如何使用 创建迁移 $ rails generate mongoid:migration &lt;your&gt; 运行迁移: $ rails db:migrate $ rails db:migrate:down VERSION= $ rails db:...

    Ruby on Rails中文指南

    在Ruby on Rails中文指南中,你将全面学习到如何利用这个强大的框架来构建动态的、数据驱动的Web应用程序。 首先,让我们深入理解Rails的核心概念: 1. **路由(Routes)**:Rails的路由系统是应用程序的导航蓝图...

    PHP Database Migrations-开源

    - **项目迭代**:在项目开发过程中,当需要增加新表、修改字段或删除无用数据时,使用迁移可以保证团队成员在不同阶段都能访问到正确的数据库状态。 - **多环境部署**:在开发、测试和生产环境之间切换时,迁移可以...

    Ruby on Rails入门例子

    - **数据库迁移(Database Migrations)**:Rails使用迁移来管理数据库结构的变化。通过`rails generate migration AddTitleToPosts title:string`创建迁移,然后运行`rails db:migrate`执行迁移。 - **...

    中文版rails教程

    2. **数据库迁移(Database Migrations)**:Rails使用ActiveRecord和SQLite、MySQL或PostgreSQL等数据库系统交互。开发者通过编写迁移文件来定义和修改数据库结构。 3. **路由(Routing)**:Rails的路由系统根据...

    Rails 3 in Action

    6. **测试驱动开发(TDD)**:Rails强调TDD,书中介绍了Rspec、Cucumber等测试工具的使用,以及如何编写单元测试和集成测试。 7. **RESTful设计**:Rails鼓励使用RESTful风格来设计Web服务,书中讲解了如何实现CRUD...

    使用Aptana+Rails开发Rails Web应用(中文)

    例如,要在Rails应用中创建一个新的资源,如博客文章,你需要在models目录下创建一个名为`post.rb`的文件,定义Post类,并设置属性如标题和内容。在controllers目录下创建`posts_controller.rb`,定义控制器方法,如...

    rails 项目起步示例

    学习Rails项目起步,你需要熟悉这些核心概念,并掌握如何创建和运行Rails应用,以及如何使用Rails的命令行工具。同时,理解MVC模式和Rails的约定优于配置(Convention Over Configuration, CoC)原则是至关重要的。...

    Ruby+for+Rails

    在Rails中,可以配置数据库连接信息,使用`database.yml`文件。安装MySQL后,通过Gemfile中的`gem 'mysql2'`来添加MySQL驱动,接着运行`bundle install`安装依赖。 4. **Rails基础知识** - **模型(Model)**:...

    ruby on rails 实例depot

    4. **模型(Models)**:在Rails中,模型代表数据模型和业务逻辑。例如,Depot可能有Product、Order和Cart等模型,每个模型对应数据库中的一个表。你可以使用`rails generate model`命令创建新模型。 5. **迁移...

    ruby on rails轻松使用

    14. **数据库迁移(Database Migrations)**: 当数据库结构需要变化时,使用`rails generate migration`创建迁移文件,然后通过`rails db:migrate`来执行迁移。 15. **Rails Console**: 交互式的命令行工具,可以...

    基于ruby on rails开发示例源码

    在Rails中,`模型`负责处理数据和业务逻辑,`视图`负责展示用户界面,而`控制器`则作为模型和视图之间的桥梁,处理用户请求并协调它们之间的交互。Rails的许多特性,如ActiveRecord(ORM)、ActiveModel、Action...

    nova-rails-migrations:提供命令以轻松访问Rails项目中的迁移

    适用于Nova的Rails迁移扩展提供命令以轻松访问Rails项目中的迁移。特征快速打开最新的Rails迁移从您的迁移列表中选择一个特定的迁移安装下载最新。 解压缩档案。 双击RailsMigrations.novaextension将扩展安装在Nova...

    Ruby on Rails Tutorial Learn Rails by Example 的源代码

    `sample_app`中的每个模型文件(如`app/models/user.rb`)都展示了如何定义数据模型及其属性和关系。 5. **控制器**:`app/controllers`目录下的文件(如`application_controller.rb`和用户相关的`users_controller...

    Rails3常用命令行命令

    在控制台中,你可以直接操作应用的数据模型和执行各种Ruby代码,进行数据查询和调试。 为了启动Rails应用的服务,你可以运行: ```bash rails server -p *** ``` 这里的`***`代表你想让服务器监听的端口号。默认...

    nonschema_migrations:在Rails应用程序中将架构与数据迁移分开

    Rails版本使用此宝石的版本Rails 4.x,4.1.x,4.2 v1.0.1(2019年6月1日发布) Rails 5.0 v2.0.1(2019年6月1日发布) Rails 5.1 v3.0.1(2019年6月1日发布) Rails 5.2 v4.0.2(2019年6月2日发布) Rails 6.0 v...

    web开发之rails最新调试通过购物车代码

    6. **数据库迁移(Database Migrations)**:Rails提供了方便的工具来创建和更新数据库结构。购物车功能可能涉及到创建新的表,如`cart_items`和`orders`。 7. **测试(Testing)**:为了确保代码的健壮性和正确性...

    good-migrations:在运行数据库迁移时防止Rails自动加载应用程序代码

    good_migrations 警告:good_migrations当前不适用于zeitwerk,这是Rails中的当前自动加载器实现。 参见 ... 这意味着,如果您的迁移引用了您在app/models定义的ActiveRecord模型对象,则旧的迁移可能

Global site tag (gtag.js) - Google Analytics