Currently, to rebuild my database for a Rails project, I run the following Rake tasks in the command line:
bundle exec rake db:drop
bundle exec rake db:create
bundle exec rake db:migrate
bundle exec rake db:seed
I would like to put these inside of a single Rake task, so I created a lib/tasks/db.rake
file:
namespace :db do
desc 'Drop and recreate the database(s)'
task :clean do
Rake::Task["db:drop"].invoke
Rake::Task["db:create"].invoke
Rake::Task["db:migrate"].invoke
Rake::Task["db:seed"].invoke # This doesn't work for some reason...
end
end
The first few tasks run fine, but db:seed
crashes with a strange error:
undefined method `username' for #<User:0xdfaa494>
[...]/gems/activemodel-3.2.12/lib/active_model/attribute_methods.rb:407:in `method_missing'
[...]/gems/activerecord-3.2.12/lib/active_record/attribute_methods.rb:149:in `method_missing'
[...]/lib/acts_as_followable/followable.rb:42:in `method_missing'
[...]/gems/friendly_id-4.0.9/lib/friendly_id/slugged.rb:253:in `should_generate_new_friendly_id?'
[...]/gems/friendly_id-4.0.9/lib/friendly_id/slugged.rb:273:in `set_slug'
[...]/gems/activesupport-3.2.12/lib/active_support/callbacks.rb:407:in `_run__819679792__validation__197267883__callbacks'
[...]/gems/activesupport-3.2.12/lib/active_support/callbacks.rb:405:in `__run_callback'
[...]/gems/activesupport-3.2.12/lib/active_support/callbacks.rb:385:in `_run_validation_callbacks'
[...]/gems/activesupport-3.2.12/lib/active_support/callbacks.rb:81:in `run_callbacks'
[...]/gems/activemodel-3.2.12/lib/active_model/validations/callbacks.rb:53:in `run_validations!'
[...]/gems/activemodel-3.2.12/lib/active_model/validations.rb:195:in `valid?'
[...]/gems/activerecord-3.2.12/lib/active_record/validations.rb:69:in `valid?'
[...]/gems/activerecord-3.2.12/lib/active_record/validations.rb:77:in `perform_validations'
[...]/gems/activerecord-3.2.12/lib/active_record/validations.rb:50:in `save'
[...]/gems/activerecord-3.2.12/lib/active_record/attribute_methods/dirty.rb:22:in `save'
[...]/gems/activerecord-3.2.12/lib/active_record/transactions.rb:259:in `block (2 levels) in save'
[...]/gems/activerecord-3.2.12/lib/active_record/transactions.rb:313:in `block in with_transaction_returning_status'
[...]/gems/activerecord-3.2.12/lib/active_record/connection_adapters/abstract/database_statements.rb:192:in `transaction'
[...]/gems/activerecord-3.2.12/lib/active_record/transactions.rb:208:in `transaction'
[...]/gems/activerecord-3.2.12/lib/active_record/transactions.rb:311:in `with_transaction_returning_status'
[...]/gems/activerecord-3.2.12/lib/active_record/transactions.rb:259:in `block in save'
[...]/gems/activerecord-3.2.12/lib/active_record/transactions.rb:270:in `rollback_active_record_state!'
[...]/gems/activerecord-3.2.12/lib/active_record/transactions.rb:258:in `save'
[...]/gems/activerecord-3.2.12/lib/active_record/relation/finder_methods.rb:294:in `find_or_instantiator_by_attributes'
[...]/gems/activerecord-3.2.12/lib/active_record/dynamic_matchers.rb:52:in `method_missing'
[...]/db/core_data/roles_and_users.rb:7:in `<top (required)>'
[...]/gems/activesupport-3.2.12/lib/active_support/dependencies.rb:245:in `load'
[...]/gems/activesupport-3.2.12/lib/active_support/dependencies.rb:245:in `block in load'
[...]/gems/activesupport-3.2.12/lib/active_support/dependencies.rb:236:in `load_dependency'
[...]/gems/activesupport-3.2.12/lib/active_support/dependencies.rb:245:in `load'
[...]/db/seeds.rb:20:in `block in <top (required)>'
[...]/db/seeds.rb:19:in `each'
[...]/db/seeds.rb:19:in `<top (required)>'
[...]/gems/activesupport-3.2.12/lib/active_support/dependencies.rb:245:in `load'
[...]/gems/activesupport-3.2.12/lib/active_support/dependencies.rb:245:in `block in load'
[...]/gems/activesupport-3.2.12/lib/active_support/dependencies.rb:236:in `load_dependency'
[...]/gems/activesupport-3.2.12/lib/active_support/dependencies.rb:245:in `load'
[...]/gems/railties-3.2.12/lib/rails/engine.rb:520:in `load_seed'
[...]/gems/activerecord-3.2.12/lib/active_record/railties/databases.rake:333:in `block (2 levels) in <top (required)>'
[...]/lib/tasks/db.rake:11:in `block (2 levels) in <top (required)>'
[...]/bin/ruby_noexec_wrapper:14:in `eval'
[...]/bin/ruby_noexec_wrapper:14:in `<main>'
Tasks: TOP => db:seed
This error doesn't occur on the command line, or when running the app.
UPDATE: Here is more info about the code base and schema.
Line 7 of db/core_data/roles_and_users.rb
:
admin_user = User.find_or_create_by_email('valid@example.com') # not the actual email address used in the file
Portions of the app/models/user.rb
:
class User < ActiveRecord::Base
include ApplicationHelper, FriendlyId, ActsAsFollowable::Followable, Disableable
...
friendly_id :username, :use => :slugged
attr_accessible :username
...
username_format = /^[a-z\d]+([-_][a-z\d]+)*$/i
validates :username, :presence => true, :uniqueness => true, :format => { :with => username_format, :message => "can only contain letters, numbers, underscores (_) or dashes (-). Spaces are not allowed."}, :unreserved_word => true, :length => { :minimum => 3, :maximum => 60 }
...
end
username
is a VARCHAR(255) field in the database.
UPDATE 2: It looks like the Rake environment is not being set up correctly. If I replace line 7 in db/core_data/roles_and_users.rb
with the following:
admin_user = User.create(:email => 'valid@example.com', :username => 'administrator')
Then the error is:
unknown attribute: username
If I compare the output of manual invocation from the command line (which works) against Rake, and I also output the User model:
# Command line invocation -- WORKS
[2013-03-25 09:42:08] INFO Rails : Connecting to database specified by database.yml
** Invoke db:load_config (first_time)
** Execute db:load_config
** Execute db:abort_if_pending_migrations
Creating badges...
Creating Shipping Options...
For UPS...
For USPS...
Creating roles...
Creating users...
User(id: integer, email: string, encrypted_password: string, reset_password_token: string, reset_password_sent_at: datetime, remember_created_at: datetime, sign_in_count: integer, current_sign_in_at: datetime, last_sign_in_at: datetime, current_sign_in_ip: string, last_sign_in_ip: string, created_at: datetime, updated_at: datetime, last_day_logged_in: datetime, consecutive_days_logged_in: integer, username: string, confirmation_sent_at: datetime, confirmed_at: datetime, confirmation_token: string, failed_attempts: integer, unlock_token: string, locked_at: datetime, super_user: boolean, facebook_id: string, facebook_email: string, fb_auth_token: string, slug: string, forem_admin: boolean, forem_state: string, forem_auto_subscribe: boolean, disabled: boolean, delta: boolean, latitude: float, longitude: float)
# Rake invocation -- DOESN'T WORK
** Invoke db:schema:load (first_time)
** Invoke environment
** Invoke db:load_config
** Execute db:schema:load
** Invoke db:seed (first_time)
** Execute db:seed
** Invoke db:abort_if_pending_migrations
Creating badges...
Creating Shipping Options...
For UPS...
For USPS...
Creating roles...
Creating users...
User(id: integer, email: string, encrypted_password: string, reset_password_token: string, reset_password_sent_at: datetime, remember_created_at: datetime, sign_in_count: integer, current_sign_in_at: datetime, last_sign_in_at: datetime, current_sign_in_ip: string, last_sign_in_ip: string, created_at: datetime, updated_at: datetime)
rake aborted!
undefined method `username' for #<User:0xdad7fc0>
As you can see, Rake doesn't see a lot of the model's fields, even though they exist in the database.
I don't know if this would work, but try with:
namespace :db do
desc 'Drop and recreate the database(s)'
task :clean => :environment do
...
end
end
UPDATE: If this is the complete code of your task, you can define a task that executes others as follows:
namespace :db do
desc 'Drop and recreate the database(s)'
task :clean => [:drop, :create, :migrate, :seed]
end
Hope this helps! :)
UPDATE 2:I guess I didn't read the backtrace properly... The error says that your User object has no username
method defined. This can be caused by 2 different errors:
You should have defined the username
method manually.
You have added a username
field in your migrations, but somehow it's not there.
Check spellwritings on the migrations and confirm you didn't need to implement option 1. Then check your db/core_data/roles_and_users.rb:7
file (extracted from the backtrace).
If this doesn't solve your problem, I don't know what else to do :(
Though it's kind of a roundabout solution, in your db:clean
task I'd try executing the commands by using system()
or wrapping the rake calls in backticks, ie:
system("bundle exec rake db:drop")
system("bundle exec rake db:create")
system("bundle exec rake db:migrate")
system("bundle exec rake db:seed")
or
`bundle exec rake db:drop`
`bundle exec rake db:create`
`bundle exec rake db:migrate`
`bundle exec rake db:seed`
With that said, I haven't tested it but it should work.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.