2

Im trying to create a record in my migration but I am having trouble I've done it before (with the help of my senior developer) and I tried to replicate what he's done but it does not seem to create the record in the database...

Heres the migration file

class PageEditor < ActiveRecord::Base; end

def create_initial_record
  PageEditor.create({
    :title => 'Events & Training',
            :content => ''
  })
  PageEditor.create({
    :title => 'Roof Mount - Training',
            :content => ''
  })
end

class CreatePageEditors < ActiveRecord::Migration
  def up
    create_table :page_editors do |t|
      t.string :title
      t.text :content

      t.timestamps
    end

    create_initial_record
  end

  def down
drop_table :page_editors
  end
 end

So i've added the roof mount - training part and then ran a rake db:migrate but it does not create the record and does not show up on my index page.......

iltempo
  • 15,718
  • 8
  • 61
  • 72
user1502223
  • 645
  • 2
  • 10
  • 27
  • I feel like I'm doing the same thing as the post you mentioned but it does not add the field for some reason.....any help would be appreciated – user1502223 Apr 24 '13 at 20:37

4 Answers4

7

See http://edgeguides.rubyonrails.org/migrations.html#migrations-and-seed-data

A better way is to use Rails 'seed' feature: In the db/seeds.rb file:

PageEditor.create({:title => 'Events & Training', :content => ''})
PageEditor.create({:title => 'Roof Mount - Training', :content => ''})

Then run rake db:seed

Jordan Allan
  • 4,408
  • 7
  • 32
  • 35
  • 1
    I've heard of that but i dont wanna deviate much from what my senior developer has done......Why would just adding another PageEditor.create not work though? Very frustrated....thank you for the tip though – user1502223 Apr 24 '13 at 20:41
  • im just gonna go with your solution! Thanks a lot very easy and clean and works like a charm – user1502223 Apr 24 '13 at 20:46
4

Well the easy solution is write another migration like add_values_to_page_editors

and in that

class AddValuesToPageEditors < ActiveRecord::Migration
  def up
    page_editor1 = PageEditor.create!({:title => 'Events & Training', :content => ''})
    page_editor2 = PageEditor.create!({:title => 'Roof Mount - Training', :content => ''})
  end

  def down
    page_editor1 = PageEditor.find_by_title( 'Events & Training' )
    page_editor1.destroy
    page_editor2 = PageEditor.find_by_title( 'Roof Mount - Training' )
    page_editor2.destroy       
  end
end
Leventix
  • 3,789
  • 1
  • 32
  • 41
user2316072
  • 111
  • 2
4

Try PageEditor.reset_column_information after creating the table. Otherwise ActiveRecord will be acting based on old data.

You should also consider embedding a skeleton version of PageEditor in your migration. This prevents issues with validations tripping up your create calls, or with later versions of the model interfering with older migrations that hadn't anticipated them. Example:

class ManufactureWidgets < ActiveRecord::Migration
  class Widget < ActiveRecord::Base; end
  def change
    create_table :widgets do |t|
      t.timestamps
    end

    Widget.reset_column_information
    Widget.create!
  end
end

It's important to recall that migrations are not always run to build a database. They should be used to migrate from one schema to another, and when deploying in more stable environments it is common to run rake db:schema:load, which bypasses the migrations entirely and simply builds the database based on the information in schema.rb.

Seed data is poorly implemented in Rails, unfortunately, but there are a number of third party libraries with different philosophies on handling this. If you're the junior developer on a project that is already embedding seed data in your migrations you should either flag it to the senior developer and propose a change; when that is inappropriate or infeasible, it's appropriate to simply follow the established pattern.

coreyward
  • 77,547
  • 20
  • 137
  • 166
  • I prefer to not use model classes at all in my migrations. If I need to CRUD some data in a migration then I do it by hand with SQL and `connection.execute`. Much easier to keep migrations and models from getting out of sync that way; your skeleton model class should achieve the same effect. – mu is too short Apr 24 '13 at 21:24
  • @muistooshort Using SQL works sometimes, but other times you end up porting a decent amount of logic over to SQL to get the same effect. This is one reason why I believe Rails' migration/DB tools fall short. And if you're concerned about Rails loading `app/models/widget.rb`, you needn't be thanks to the scope: `ManufactureWidgets::Widget` is resolved first, so your migration doesn't use `YourApp::Widget`. – coreyward Apr 25 '13 at 18:44
  • My problem with using models in migrations is that the database as the migration expects it to be and the database as the model expects it to be are often different: associations might change, tables could be dropped or created, columns may be added or removed, validation constraints may not be the same, etc. So either you make local copies of all the models involved or you do it in SQL. I think the entire Rails attitude towards databases falls far short and the whole "no logic in the database" attitude is a bit absurd and short sighted. Good point on the scoping though. – mu is too short Apr 25 '13 at 19:12
2

In your migration instead of

create_initial_record

Use

PageEditor.create_initial_record!

Hope this will work.This is the solution you wanted :-)

user2316072
  • 111
  • 2