Add Rows on Migrations

前端 未结 5 1805
故里飘歌
故里飘歌 2020-12-15 18:41

I\'d like to know which is the preferred way to add records to a database table in a Rails Migration. I\'ve read on Ola Bini\'s book (Jruby on Rails) that he does something

相关标签:
5条回答
  • 2020-12-15 18:49

    You could use fixtures for that. It means having a yaml file somewhere with the data you want to insert.

    Here is a changeset I committed for this in one of my app:

    db/migrate/004_load_profiles.rb

    require 'active_record/fixtures'
    
    class LoadProfiles < ActiveRecord::Migration
      def self.up
        down()
    
        directory = File.join(File.dirname(__FILE__), "init_data")
        Fixtures.create_fixtures(directory, "profiles")
      end
    
      def self.down
        Profile.delete_all
      end
    end
    

    db/migrate/init_data/profiles.yaml

    admin:
     name: Admin
      value: 1
    normal:
     name: Normal user
      value: 2
    
    0 讨论(0)
  • 2020-12-15 18:53

    You could also define in your seeds.rb file, for instance:

    Grid.create :ref_code => 'one' , :name => 'Grade Única'
    

    and after run:

    rake db:seed
    
    0 讨论(0)
  • 2020-12-15 18:54

    The Rails API documentation for migrations shows a simpler way to achieve this.

    http://api.rubyonrails.org/classes/ActiveRecord/Migration.html

    class CreateProductCategories < ActiveRecord::Migration
      def self.up
        create_table "product_categories" do |t|
          t.string name
          # etc.
        end
    
        # Now populate the category list with default data
    
        ProductCategory.create :name => 'Books', ...
        ProductCategory.create :name => 'Games', ... # Etc.
    
        # The "down" method takes care of the data because it
        # drops the whole table.
    
      end
    
      def self.down
        drop_table "product_categories"
      end
    end
    

    Tested on Rails 2.3.0, but this should work for many earlier versions too.

    0 讨论(0)
  • 2020-12-15 19:05

    your migrations have access to all your models, so you shouldn't be creating a class inside the migration.

    I am using the latest rails, and I can confirm that the example you posted definitely OUGHT to work.

    However, migrations are a special beast. As long as you are clear, I don't see anything wrong with an ActiveRecord::Base.connection.execute("INSERT INTO product_types (name) VALUES ('type1'), ('type2')").

    The advantage to this is, you can easily generate it by using some kind of GUI or web front-end to populate your starting data, and then doing a mysqldump -uroot database_name.product_types.

    Whatever makes things easiest for the kind of person who's going to be executing your migrations and maintaining the product.

    0 讨论(0)
  • 2020-12-15 19:06

    You should really not use

    ProductType.create
    

    in your migrations.

    I have done similar but in the long run they are not guaranteed to work.

    When you run the migration the model class you are using is the one at the time you run the migration, not the one at the time you created the migration. You will have to be sure you never change your model in such a way to stop you migration from running.

    You are much better off running SQL for example:

    [{name: 'Type', ..}, .. ].each do |type|
      execute("INSERT INTO product_types (name) VALUES ('#{type[:name]} .. )
    end
    
    0 讨论(0)
提交回复
热议问题