I have run into a very strange problem. I have a task which resets my database as so:
task :reset => [:drop, :create, :migrate, :seed]
The problem is, I am receiving errors when seeding because of missing columns which are added in late migration files. One example:
undefined method new_attr= for User
Yet this attribute is already added in a migration. The strange part is, I receive no errors if I run the above tasks separately. Can anybody shed some light? Surely these tasks cannot be run asynchronously.
Another way to avoid errors is to amend my earlier migrations create_ with the new attributes. Then running :reset doesn't trigger errors for those attributes.
The migrations are clearly fine as I can run the above tasks separately, just not bundled under a single task.
maybe you want to make your reset task more explicit?
namespace :db_tasks do
desc "Rebuild development db"
task :rebuild_database, [] => :environment do
raise "Only run in development or staging" if Rails.env.production?
Rake::Task['db:drop'].execute
Rake::Task['db:create'].execute
Rake::Task['db:migrate'].execute
Rake::Task['db:seed'].execute
Rake::Task['db:test:prepare'].execute
end
end
Probably your problem is already solved using this:
rake db:reset
The rake db:reset task will drop the database, recreate it and load the current schema into it.
Have you tried with namespace?
task :reset => [db:drop, db:create, db:migrate, db:seed]
If these rake tasks are executed in the production mode,
model attributes are cached. Even though migrations work perfect, it wont apply to the cached.
This will break your succeeding seed as newly added columns will be missing in the cache.
A possible solution is to reload your rails environment before seeding.
Related
I am using http://rails-erd.rubyforge.org/ to generate an ERD - the output is a very nice diagram of my project's object model. There is also a rake task to generate the ERD, generate_erd, that I would like to have invoked automatically after I run rake db:migrate. How do I do that?
The given link by #MaxWilliams is a helpful but I don't think any of those answers quite do what you want. I found this article on Rake Task Overwriting. It's from 2008, but I tried this out and it worked.
I created another .rake file (for organization) and just happened to call mine migrate_and_generate_erb.rake but name it whatever you want.
Inside I just had this:
namespace :db do
task :migrate do
Rake::Task["erd"].invoke
end
end
Basically, according to the article, Rake just keeps appending code implementation to the task if it's already defined.
Now running rake db:migrate also generated me my ERD.
Careful: You'll also want to do the same for db:rollback so that rolling back a migration also updates your ERD.
One last note: consider also just aliasing this (shell command), just in case you'd ever want to run the migrate without generate the ERD, or use environment variables along with your new Rake task.
I have seeded a row of data to my table by editing db/seed.rb file and executing rake db:seed command. Unknowingly, I put some wrong information in to that row. So I want to remove the previously added row of data. Is there any rake command for the same like rake db:rollback for rake db:migrate.
There are a couple of aspects to this:
1: You want to change the seed data when no other data is present in the database:
You should simply redo the rake db:seed after updating the seed.rb file. Make sure you have MyModel.delete_all before you try to add anything to that model.
2: You want to change the seed data, but there are other data added to the database
This is a bit harder. Often the simplest thing to do here is to manually change the data with either raw sql-statements, or with the use of tools like PhpPpAdmin, PhpMyAdmin etc.
Now, there is possiby one way to hack this together, and that would be to do some voodoo in the seed.rb file. So you could run rake db:seed deseed=true, then in your seed.rb:
if ENV['deseed']
#Do your deseeding action here
else
#Do your seeding here.
end
You could even get real crazy and do something like this:
deseed = ENV['desee']
#DANGER: Dirty hacks upcoming:
deseed? myModelCall = MyModel.method(:destroy_all): myModelCall = MyModel.method(:create)
myModelCall.call :user_id_or_whatevs => 23 #this creates or deletes a MyModel entity with the given parameters
#NOTE this might not work in all cases and I would not necessarily recommend doing this.
#<3uby
I had similar issues when I seeded my data. In fact, I ran the seed command twice and I couldn't find a way to revoke the second seed. However, I had to run rails db:reset command and then run the rails db:seed command again and that fixed the problem for me.
I have a batch of rake tasks that run sequentially:
task :batch_tasks => :environment do
Rake::Task["db:drop"].execute
Rake::Task["db:create"].execute
Rake::Task["db:migrate"].execute
Rake::Task["db:seed"].execute
Rake::Task["db:test:prepare"].execute
Rake::Task["custom_task_1"].execute
end
Here's what's in custom_task_1:
task :custom_task_1 => :environment do
puts "begin custom task"
orders = Order.all #three records
orders.each do |order|
puts "Do something to Order\n"
end
puts "end custom task"
end
When I run the above batch process, here's what happens:
rake batch_tasks
begin custom task
end custom task
But if I run the custom task AFTER the batch process, here's what happens:
rake custom_task_1
begin custom task
Do something to Order
Do something to Order
Do something to Order
end custom task
One thing to note, when I run debugger on rake batch_tasks with a breakpoint after rake db:seed, a check on eval Order.all returns an empty array []. However, Order.all does have data immediately after all of the rake tasks are finished.
What am I missing about rake db:seed and having access to ActiveRecord data in the next task called?
As mu is too short suggested, this is related to the need to reload models before using them in migrations. The reason for this is that all of your rake tasks run in a common environment, ie, it only loads rails once. As such, the table definitions may already be established. You will probably have to use reset_column_information to load the new values.
Alternately, the sequence of tasks you are doing look like they should be run independently, which could be a good use case for capistrano or thor.
So the quick fix was to move the db:test:prepare line to the end of the batch.
I believe the problem stemmed from the environment being switched from development to test and then the custom task was running in the last environment, which then had an empty test database.
The db:seed command probably switches the environment back to dev and the custom task runs against the correct database.
task :batch_tasks => :environment do
Rake::Task["db:drop"].execute
Rake::Task["db:create"].execute
Rake::Task["db:migrate"].execute
Rake::Task["db:seed"].execute
Rake::Task["custom_task_1"].execute
Rake::Task["db:test:prepare"].execute # <-- Moved after all other tasks
end
I have some problems with one of gem supporting ActiveModel caching. When I'm using observer for cached model, during application initialization it tries to describe table to get all fields names.
The same thing is done when rake task is running, including db:migration. In that case there is some circular reference error. I'd like to detect current rake task, to skip gem initialization, but I don't know how to find out was code invoked through rake task. How to check it?
I dont get exactly what you are trying to do, but here is an example of getting the task name.
task :testing do |task_name|
puts task_name
end
This question has been asked a few places, and I didn't think any of the answers were very good... I think the answer is to check Rake.application.top_level_tasks, which is a list of tasks that will be run. Rake doesn't necessarily run just one task.
If you run your task via rake task or bundle exec rake task you can check it in your initializer simply by:
if $0.end_with?('rake')
# rake stuff
else
# non-rake stuff
end
You can use $PROGRAM_NAME instead of $0 if you like.
My Environment -> Ruby 1.9.2 and Rails v3.0.5
I noted a strange pattern in rake db:reset. According to rails source code, rake db:reset will => db:drop, db:create and db:migrate. https://github.com/rails/rails/blob/v3.0.5/activerecord/lib/active_record/railties/databases.rake#L159
Setup: One of my migration files have Model.create statements to populate some data (Forgive me, I'm not the one who had put data-filling-code in those migrations :) ..)
Case 1: When I do the steps manually, i mean drop, create, and migrate, one by one - those statements fill data in the table.
Case 2: When I do just rake db:reset, schema is set properly. but the data is not entering the db. Does db:reset skip create/update statements.. I have tried this several times to make sure that I have no faults in the steps I do. I still get this behavior.
what is going wrong here... ?
I think you're reading the wrong line in the source. As I read it:
db:migrate:reset # => [:drop, :create, :migrate]
db:reset # => [:drop, :setup]
So db:reset just create the tables and sets the migrations as if they had been run, without actually running them. db:migrate:reset actually runs each migration.
I had the same problem before but I was running 3.0.3, and it turns out, somehow I manage to mess up the migrations by change the migrations files and not running the migrations(forgot about it or something)...I'll start by checking those files