rspec tests are failing b/c application_controller is making db calls - mysql

I have some simple rspec tests that check if a particular page's title is 'xxxx'.
I added some before_filter's to my application_controller which makes db calls.
Should I be mocking these out somehow?
The tests are failing saying "mysql2::error table myapp_test.articles doesn't exist.

That sounds more like you need to run rake db:test:prepare or rake db:migrate db:test:prepare to me. Do you have something set up so your rspecs fail when they hit the database intentionally?

Related

Localhost launch fails due to pending migration error

Issue: I am unable to launch localhost of the website we are developing in my local system. So I could play with it and write automated tests. Earlier it used to work.
The commands I run usually after Fetching Origin - of the Develop branch through Github app
bundle install
rake db:migrate
rails s
Now, the rake db:migrate is not working, giving me an error
Macs-iMac:mac$ bin/rails db:migrate RAILS_ENV=development
== 20180619223217 CreateCarts: migrating ======================================
-- create_table(:carts)
rails aborted!
StandardError: An error has occurred, all later migrations canceled:
Mysql2::Error: Table 'carts' already exists: CREATE TABLE carts
(id bigint NOT NULL AUTO_INCREMENT PRIMARY KEY, user_id int,
created_at datetime NOT NULL, updated_at datetime NOT NULL)
ENGINE=InnoDB
/Users/mac/.rvm/gems/ruby-2.4.1/gems/mysql2-0.4.10/lib/mysql2/client.rb:120:in
`_query'
/Users/mac/.rvm/gems/ruby-2.4.1/gems/mysql2-0.4.10/lib/mysql2/client.rb:120:in
`block in query'
/Users/mac/.rvm/gems/ruby-2.4.1/gems/mysql2-0.4.10/lib/mysql2/client.rb:119:in
`handle_interrupt'
/Users/mac/.rvm/gems/ruby-2.4.1/gems/mysql2-0.4.10/lib/mysql2/client.rb:119:in
`query'
.. many lines like this..
There are many tables at least 8 of them like "carts" already exists it says.
Following troubleshooting have been done.
I tried to do rake db:reset / rails db:reset - It gave me error like "You are attempting to run a destructive action"
imported new data for the dev table on Sequelpro, then ran rake db:migrate
None of these three commands also worked, same "destructive action" error. rails db:drop, rails db:schema:load, rails db:reset
I went into db/migrate folder, and in-commented the lines that create those 8 issue tables.
This seems to work, able to launch the app, but obviously some menus in the app don't work.
Switching through older versions of the app I had in the system in different feature branches I created months back, is working.
How do I solve this? and get on to launch the app :)
Use rails db:reset DISABLE_DATABASE_ENVIRONMENT_CHECK=1in (1)

CakePHP 3 Migrations Plugin Error when running bin/cake Migrations migrate

I pretty much use Migrations every time I work with CakePHP and I never encounter any issues.
This time, however, I am having an issue trying to execute the following command
bin/cake Migrations migrate
I had created the file using
bin/cake bake migrations CreateTaxes state:string[5] ...
The file created successfully, but when I run the command to migrate, I am getting the following error:
PHP Fatal error: Class Migrations\CakeAdapter contains 1 abstract method
and must therefore be declared abstract or implement the remaining methods
(Phinx\Db\Adapter\AdapterInterface::getVersionLog) in
/var/www/taxes/website/vendor/cakephp/migrations/src/CakeAdapter.php
on line 670
I cant figure out why it is throwing this error and not allowing the command to finalize. I have looked at both CakeAdapter.php and AdapterInterface.php for Phinx.
This was actually a bug that has now been fixed. https://github.com/cakephp/migrations/issues/202

Migration error with devise

Hey I have a problem with my page here. I used a gem 'devise' to create a migration file for "users" I might have forgotten to rake db:migrate after that but I'm really not too sure what I did here to duplicate anything.
I ran the code rails g devise user I may have forgotten to db:migrate and then ran the code rails g devise:views
It's for a TeamTreeHouse project, and I'm sorry if I was too confusing with my question...anyway here is the error message.
== AddDeviseToUsers: migrating ===============================================
-- change_table(:users, :email)
rake aborted!
An error has occurred, this and all later migrations canceled:
SQLite3::SQLException: duplicate column name: email: ALTER TABLE "users" ADD "email" varchar(255) DEFAULT '' NOT NULL
Tasks: TOP => db:migrate
(See full trace by running task with --trace)
It seems you already have an "users" table
Try to run: rake db:reset to run your migrations after drop and recreate your database.
UPDATE
This command will clear all data you have stored (unless is present in your seeds.rb), be careful to use this if you have important data in your database.
his command will clear all data you have stored (unless is present in your seeds.rb), be careful to use this if you have important data in your database.

spork/guard reload schema

I use spork and guard to speed up the test suite in my Rails 3.2 application. However the tests in guard behave strange after adding a new migration: they act as they don't know about the changes in schema, even though I run rake db:migrate before. They start to behave correctly when I stop guard and run rake spec. I suppose that it behaves this way, because spork/guard doesn't update schema before tests. Is it possible to configure spork to update schema on #prefork and guard to reload spork on schema changes?
You need to run rake db:test:prepare to apply migrations for testing environment.
Theoretically the following default Spork setup code should reload schema each time a test is run. Do you have it?
ActiveRecord::Schema.verbose = false
silence_stream STDOUT do
load Rails.root.join('db', 'schema.rb') # use db agnostic schema by default
load Rails.root.join('db', 'seeds.rb')
end

db:schema:load vs db:migrate with capistrano

I have a rails app that I'm moving to another server and I figure I should use db:schema:load to create the mysql database because it's recommended. My problem is that I'm using capistrano to deploy and it seems to be defaulting to rake db:migrate instead. Is there a way to change this or is capistrano using db:migrate for a good reason?
Why to use db:schema:load
I find that my own migrations eventually do some shuffling of data (suppose I combine first_name and last_name columns into a full_name column, for instance). As soon as I do any of this, I start using ActiveRecord to sift through database records, and your models eventually make assumptions about certain columns. My "Person" table, for instance, was later given a "position" column by which people are sorted. Earlier migrations now fail to select data, because the "position" column doesn't exist yet.
How to change the default behavior in Capistrano
In conclusion, I believe deploy:cold should use db:schema:load instead of db:migrate. I solved this problem by changing the middle step which Capistrano performs on a cold deploy. For Capistrano v2.5.9, the default task in the library code looks like this.
namespace :deploy do
...
task :cold do
update
migrate # This step performs `rake db:migrate`.
start
end
...
end
I overrode the task in my deploy.rb as follows.
namespace :deploy do
task :cold do # Overriding the default deploy:cold
update
load_schema # My own step, replacing migrations.
start
end
task :load_schema, :roles => :app do
run "cd #{current_path}; rake db:schema:load"
end
end
Climbing up on the shoulders of Andres Jaan Tack, Adam Spiers, and Kamiel Wanrooij, I've built the following task to overwrite deploy:cold.
task :cold do
transaction do
update
setup_db #replacing migrate in original
start
end
end
task :setup_db, :roles => :app do
raise RuntimeError.new('db:setup aborted!') unless Capistrano::CLI.ui.ask("About to `rake db:setup`. Are you sure to wipe the entire database (anything other than 'yes' aborts):") == 'yes'
run "cd #{current_path}; bundle exec rake db:setup RAILS_ENV=#{rails_env}"
end
My enhancements here are...
wrap it in transaction do, so that Capistrano will do a proper rollback after aborting.
doing db:setup instead of db:schema:load, so that if the database doesn't already exist, it will be created before loading the schema.
That's a great answer from Andres Jaan Tack. I just wanted to add a few comments.
Firstly, here's an improved version of Andres' deploy:load_schema task which includes a warning, and more importantly uses bundle exec and RAILS_ENV to ensure that the environment is set up correctly:
namespace :deploy do
desc 'Load DB schema - CAUTION: rewrites database!'
task :load_schema, :roles => :app do
run "cd #{current_path}; bundle exec rake db:schema:load RAILS_ENV=#{rails_env}"
end
end
I have submitted a feature request to have deploy:load_schema implemented in Capistrano. In that request, I noted that the 'db:schema:load vs. db:migrate' debate has already been covered in the Capistrano discussion group, and there was some reluctance to switch the deploy:cold task to using db:schema:load over db:migrate, since if run unintentionally, the former nukes the entire database whereas the latter would probably complain and bail harmlessly. Nevertheless db:schema:load is technically the better approach, so if the risk of accidental data loss could be mitigated, it would be worth switching.
In Capistrano 3 / Rails 4, the default deploy syntax has changed. You can do this instead:
desc 'Deploy app for first time'
task :cold do
invoke 'deploy:starting'
invoke 'deploy:started'
invoke 'deploy:updating'
invoke 'bundler:install'
invoke 'deploy:db_setup' # This replaces deploy:migrations
invoke 'deploy:compile_assets'
invoke 'deploy:normalize_assets'
invoke 'deploy:publishing'
invoke 'deploy:published'
invoke 'deploy:finishing'
invoke 'deploy:finished'
end
desc 'Setup database'
task :db_setup do
on roles(:db) do
within release_path do
with rails_env: (fetch(:rails_env) || fetch(:stage)) do
execute :rake, 'db:setup' # This creates the database tables AND seeds
end
end
end
end
If you're cautious of invoking the standard deploy tasks manually in the :cold task (as they may change in upcoming version or if you have a custom deploy task), you can also simply call deploy:db_setup before running deploy.
To perform db:schema:load instead of db:setup, you can simply change the rake task, like so:
desc 'Load DB Schema'
task :db_schema_load do
...
execute :rake, 'db:schema:load'
...
end