【问题标题】:Populating a Rails class in the migration在迁移中填充 Rails 类
【发布时间】:2010-10-06 05:57:11
【问题描述】:

我正在尝试为仅用作枚举的简单表创建迁移。所以我想立即用它的值填充表格。我尝试了以下方法:

class CreateUserTypes < ActiveRecord::Migration

def self.up
    create_table :user_types do |t|
      t.column :type, :string
      t.timestamps
    end
  end

  def self.down
    drop_table :user_types
  end

  UserType.create :type => "System administrator"
  UserType.create :type => "Simulation controller"
end

但我收到此错误:

rake aborted!
An error has occurred, all later migrations canceled:

Could not find table 'user_types'

我关注Rails wiki 并希望它能够工作。


谢谢。但是您的建议似乎不起作用。好吧,我看不到琴弦。

sqlite> select * from user_types; 
1||2009-02-08 12:00:56|2009-02-08 12:00:56 
2||2009-02-08 12:00:57|2009-02-08 12:00:57 

【问题讨论】:

    标签: ruby-on-rails database-design migration


    【解决方案1】:

    这是已经给出的两个答案的组合,但这应该适合你:

    class CreateUserRoles < ActiveRecord::Migration
      def self.up
        create_table :user_roles do |t|
          t.string :role
          t.timestamps
        end
    
        UserRole.create :role => "System administrator"
        UserRole.create :role => "Simulation controller"
      end
    
      def self.down
        drop_table :user_roles
      end
    end
    

    将您的类 UserType 重命名为 UserRole(以及相关的测试类,假设您使用生成器创建了所有这些类)。 Rails 使用 'type' 列进行单表继承,并在您拥有派生自基类的模型时自动使用类名填充该字段。

    【讨论】:

    • 只是想知道,为什么使用 't.string' 而不是 't.column'?这是我第一次在迁移中看到它。
    • @alamodey - t.string 替换了 rails 2.0 中的 t.column。
    【解决方案2】:

    有点跑题但值得一提:在迁移中实例化数据被认为是一种糟糕的形式,因为在生产环境中创建数据库的“官方”方式是

    rake db:schema:load
    

    这当然不会从迁移文件中加载您的数据。您可能想看看我最喜欢的插件之一:Seed_Fu。

    使用 Seed_fu,您可以在 YAML 中创建数据夹具,然后发出

    rake db:seed
    

    当您想要设置数据时。

    【讨论】:

      【解决方案3】:

      试试这个

      class CreateUserTypes < ActiveRecord::Migration
      
        def self.up
          create_table :user_types do |t|
            t.string :role
            t.timestamps
          end
      
          UserType.create :role => "System administrator"
          UserType.create :role => "Simulation controller"
        end
      
        def self.down
          drop_table :user_types
        end
      
      end
      

      是调用 rake db:migrate 时默认运行的 self.up 方法

      编辑:将列名更改为“角色”,因为“类型”保留用于单表继承。 (见 cmets)。向 Kyle Boon 道歉,最终得到了一个非常相似的答案。

      【讨论】:

      • 下一个问题:我需要做什么 rake db:migrate 将在更改迁移文件后更新数据库。 rake 似乎不如 make 对 C 有效。
      • 每个迁移文件按顺序运行。如果您对迁移文件进行更改,您应该回滚到该版本并重新运行。或者,您可以编写一个进一步的迁移文件,在原始文件的基础上进行所需的更改。
      • 这仍然不起作用,可能是因为(正如该线程中的某人所说)保留了“类型”列。
      • 是的——我想就是这样。我将更新我的代码以反映这一点。
      【解决方案4】:

      HermanD 的回答应该有效。不过我想指出,您应该小心使用名为 'type' AFAIK 的列,Rails 将该列名称用于 STI。

      【讨论】:

        【解决方案5】:
        1. 将创建语句放在里面 self.up
        2. 致电UserType.reset_column_information 创建表之后和之前 填充它。模型用户类型是 在创建表之前加载,所以 rails 已收集信息 关于数据库结构之前 表将存在。你需要重置 这样 Rails 将检查表 再次属性。
        3. 不要使用“类型”作为属性名称。它用于 STI。

          类 CreateUserTypes

          def self.up
            create_table :user_types do |t|
              t.column :role, :string
              t.timestamps
            end
          
            UserType.reset_column_information
          
            UserType.create :role => "System administrator"
            UserType.create :role => "Simulation controller"
          
          end
          
          def self.down
            drop_table :user_types
          end
          

          结束

        【讨论】:

          猜你喜欢
          • 2023-03-14
          • 2022-08-17
          • 1970-01-01
          • 2018-04-30
          • 2012-09-26
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多