Active Record error to create database - ruby-on-rails

In my spec/rails_helper.rb, i have the code bellow to create the test database if it doesn`t exits.
def database_exists?
ActiveRecord::Base.connection rescue ActiveRecord::NoDatabaseError ? false : true
end
unless database_exists?
ActiveRecord::Base.establish_connection(:"#{ENV['RAILS_ENV']}")
db_config = ActiveRecord::Base.configurations[ENV['RAILS_ENV']]
ActiveRecord::Base.connection.create_database db_config
end
but i got this error when rspec is called:
.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/activerecord-4.2.1/lib/active_record/connection_adapters/mysql2_adapter.rb:23:in `rescue in mysql2_connection': Unknown database 'my-db-test' (ActiveRecord::NoDatabaseError)
Where is the problem?
If i use system('rake db:create'), it works, but is a good pratice?

The database doesn't exist so to avoid the error you can run:
rake db:create
or you can run:
rake db:setup
This will create the database AND run the migration files.

Related

Obstacle with Ruby Rails Authentication

I am a brand new Ruby on Rails User
When I enter localhost:3000 ,
I get an error reading
Migrations are pending. To resolve this issue, run:
bin/rails db:migrate RAILS_ENV=development
You have 2 pending migrations:
20221119205559_add_devise_to_users.rb
20221119211811_drop_users_table.rb
# Raises <tt>ActiveRecord::PendingMigrationError</tt> error if any migrations are pending.
def check_pending!(connection = Base.connection)
raise ActiveRecord::PendingMigrationError if connection.migration_context.needs_migration?
end
def load_schema_if_pending!
In a nutshell, it was working before but I attempted to create a a basic authentication page(which was also working) , but for some reason when I clicked sign up I received an error also.
Thank you for any tips on how to fix this!
I have tried to
rake db:drop
rake db:create
rake db:migrate
Editing the migrate file with:
edit your migration file
class DropUsersTable < ActiveRecord::Migration
def change
drop_table :users
end
end
Then doing rake db:migrate
Also, I have run :
rails generate devise:install
rails generate devise User
bundle exec rake db:migrate

Reset database with rake task

I want to use Heroku's scheduler to reset my database once every day.
It's recommended to use rake tasks for the scheduler. This is what I've tried:
task :reset_database => :environment do
`heroku pg:reset MY_DB:URL`
`heroku run rake db:migrate db:seed`
# some other ruby commands
end
But how would I do this correctly, because putting the heroku commands within backticks, which with bash normally works, doesn't work here:
No such file or directory - heroku
Try this rake task:
namespace :reset_database do
desc "Destroy all table entries."
task :all => :environment do
ActiveRecord::Base.connection.tables.each do |table|
if table != 'schema_migrations'
table.singularize.camelize.constantize.destroy_all
end
# Use this if you want to use the normal seeds:
# Rails.application.load_seed
# Use this if you want to run another rake task:
Rake::Task["foo:bar"].invoke
end
end
end

Rake task create not getting Rails.env in db:create for ActiveRecord>=4.05

For ActiveRecord 3.2.18, in /lib/active_record/railties/databases.rake:
task :load_config do
ActiveRecord::Base.configurations = Rails.application.config.database_configuration
ActiveRecord::Migrator.migrations_paths = Rails.application.paths['db/migrate'].to_a
if defined?(ENGINE_PATH) && engine = Rails::Engine.find(ENGINE_PATH)
if engine.paths['db/migrate'].existent
ActiveRecord::Migrator.migrations_paths += engine.paths['db/migrate'].to_a
end
end
end
desc 'Create the database from DATABASE_URL or config/database.yml for the current Rails.env (use db:create:all to create all dbs in the config)'
task :create => [:load_config, :rails_env] do
if ENV['DATABASE_URL']
create_database(database_url_config)
else
configs_for_environment.each { |config| create_database(config) }
ActiveRecord::Base.establish_connection(configs_for_environment.first)
end
end
For ActiveRecord 4.0.5+, in /lib/active_record/railties/databases.rake:
task :load_config do
ActiveRecord::Base.configurations = ActiveRecord::Tasks::DatabaseTasks.database_configuration || {}
ActiveRecord::Migrator.migrations_paths = ActiveRecord::Tasks::DatabaseTasks.migrations_paths
end
desc 'Create the database from DATABASE_URL or config/database.yml for the current Rails.env (use db:create:all to create all dbs in the config)'
task :create => [:load_config] do
if ENV['DATABASE_URL']
ActiveRecord::Tasks::DatabaseTasks.create_database_url
else
ActiveRecord::Tasks::DatabaseTasks.create_current
end
end
When I call bundle exec rake db:create from a Rakefile (for a gem I'm testing), ActiveRecord 3.2.18, ActiveRecord::Base.configurations gets the information it needs from my test/config/database.yml file via Rails.application.config.database_configuration. But when calling db:create using ActiveRecord 4.0.5+, ActiveRecord::AdapterNotSpecified: database configuration does not specify adapter error. It doesn't matter whether I call it with RAILS_ENV=some_environment. How do I give ActiveRecord 4.0.5+ the database configuration it needs without monkey patching it? The ideal solution is to somehow do it my Rakefile.
I had the same problem, and I "fixed" with a monkey patch:
in your Rakefile, after you imported the active_record, I did the following:
# hack to make it works with sqlite3
module Rails
def self.root
File.dirname(__FILE__)
end
def self.env
"development"
end
end
for sure you can do whatever you want inside your "self.env" method.

Run rake db:drop without failure if database doesn't exist

This comment says:
db:drop can run without failure when db does not exist
This is exactly what I need: I need to run db:drop but without throwing an exception or halt my whole process if the database doesn't exist, just delete the database if it exists or do nothing.
How can I do that? how can I tell db:drop not to destroy my life if the database doesn't exist?
This is the code I'm experiencing the problem with (it it help):
namespace :db do
task import: :environment do
Rake::Task["db:drop"].invoke # If the database doesn't already exist, the whole import process terminates!
Rake::Task["db:create"].invoke
Rake::Task["db:migrate"].invoke
database_config = Rails.configuration.database_configuration[Rails.env]
system "psql --username=#{database_config['username']} #{database_config['database']} < PostgreSQL.sql"
end
end
Why can't you go for simple exception handling
namespace :db do
task import: :environment do
begin
Rake::Task["db:drop"].invoke # If the database doesn't already exist, the whole import process terminates!
Rake::Task["db:create"].invoke
Rake::Task["db:migrate"].invoke
database_config = Rails.configuration.database_configuration[Rails.env]
system "psql --username=#{database_config['username']} #{database_config['database']} < PostgreSQL.sql"
rescue Exception => e
p "The Exception is #{e.message}"
end
end
end

Execute a Rake task from within migration?

I have a Rake task that loads configuration data into the DB from a file, is there a correct ruby/rails way to call it on a migration up?
My objective is to sync my team DB configs, without have to broadcast then to run the task lalala
def self.up
change_table :fis_situacao_fiscal do |t|
t.remove :mostrar_endereco
t.rename :serie, :modelo
end
Faturamento::Cfop.destroy_all()
#perform rake here !
end
UPDATE
How I do now, and works:
system('rake sistema:load_data file=faturamento/cfop')
And this is the suggestion from #Ryan Bigg, and it's exception:
Rake::Task['rake sistema:load_data file=faturamento/cfop'].invoke()
.
== AlterSituacaoFiscalModeloEndereco: migrating ====================
-- change_table(:fis_situacao_fiscal)
-> 0.0014s
rake aborted!
An error has occurred, this and all later migrations canceled:
Don't know how to build task 'rake sistema:load_data file=faturamento/cfop'
Where it went wrong?
Yes there's a way to do that:
Rake::Task['your_task'].invoke
Update
Do not put rake inside the brackets, just the name of the task. You should set an ENV variable when running this:
In the console
FILE=somefile.text rake db:sistema:load_data
Calling it separately
FILE=somefile.text rake some:other:task:that:calls:it
This will be available in your tasks as ENV['file']
Note that if you call the Rake task with 'system', you need to check the process status afterwards and raise an exception if the Rake task failed. Otherwise the migration will succeed even if the Rake task fails.
You can check the process status like this:
if !($?.success?)
raise "Rake task failed"
end
Invoking the rake task is a nicer option - it will cause the migration to fail if the Rake task fails.
You can execute a rake task from within a loaded Rails environment with either Rake::Task['namespace:task'].invoke or Rake::Task['namespace:task'].execute.
You can pass data to the task inside of the invoke or execute method. Example:
Rake::Task['namespace:task'].invoke(paramValue)
This param can be handled in the rake task as follows:
namespace :namespace do
desc "Example description."
task :task, [:param] => :environment do |t, args|
puts args[:param]
...
end
end
This can be executed on the console as:
bundle exec rake namespace:task[paramValue]
More info: https://medium.com/#sampatbadhe/rake-task-invoke-or-execute-419cd689c3bd
This decision fits better, IMHO.
In your case it would be smth like this:
backup_env = ENV.slice('file') if ENV.key?('file')
ENV['file'] = 'faturamento/cfop'
Rake::Task['sistema:load_data'].invoke
ENV.delete 'file'
ENV.merge!(backup_env) if backup_env

Resources