I have a ruby app that uses ActiveRecord and sqllite. I am trying to write tests but I get this error:
Failure/Error: user = described_class.create(name: name)
ActiveRecord::StatementInvalid:
Could not find table 'users'
This is my gemfile:
source "https://rubygems.org"
gem "sinatra-activerecord"
gem "sqlite3"
group :test do
gem 'database_cleaner'
end
group :test, :development do
gem "rspec-rails", ">= 2.1.0"
gem "pry"
end
I have a spec_helper that looks like this:
RSpec.configure do |config|
ActiveRecord::Base.establish_connection(adapter: 'sqlite3', database: 'db/test.db')
end
What can I do to create a test database and run the migrations for my sqllite tests?
bin/rails RAILS_ENV=test db:migrate and/or bin/rails db:test:prepare will update your test db. You also might want to check out the Rails Testing Guides too - lots of helpful info there. Or if you want to avoid fixtures, FactoryBot is great for generating test data.
Ginnie's answer can work, but if like Sean mentionned you need an ActiveRecord only solution instead of using Rails consider this :
I recently developed a gem to bundle some ActiveRecord models without using Rails.
Here is what I did to test my models with rspec:
spec/spec_helper.rb:
ActiveRecord::Base.establish_connection(adapter: 'sqlite3',
database: ':memory:')
ActiveRecord::Schema.define do
require_relative '../lib/db/migrate/create_models'
end
lib/db/migrate/create_models.rb: (to make this file I copy/pasted the actual schema.rb generated by migrations)
class CreateModels < ActiveRecord::Migration[5.1]
create_table "users", force: :cascade do |t|
t.string "uid", default: "", null: false
t.string "email", null: false
// other attributes
end
// other tables
end
This will create your needed tables for your tests to run.
Don't forget to require spec_helper in your *_spec.rb file and you're good to go.
Related
everyone one I am working on a Sinatra app. I am trying to use Active Record as my database option. This is my first time of using Active Record with Sinatra.
I have successfully created my table, but I am getting an error whenever I try to "rake db:migrate".
I have gone through likely issues I found on Stack overflow, but not getting any headway. Any help would be appreciated.
Error message for "rake db:migrate
rake aborted!
ActiveRecord::ConnectionNotEstablished: ActiveRecord::ConnectionNotEstablished
Tasks: TOP => db:migrate
(See full trace by running task with --trace)
Below is my Rakefile
require_relative './app/controllers/recipe_controller'
require 'sinatra/activerecord/rake'
task :console do
Pry.start
end
Below is my config/environment file
require 'bundler'
require 'bundler/setup'
Bundler.require
ActiveRecord::Base.establish_connection(
adapter: 'sqlite3',
database: 'db/development.sqlite'
)
require './app/controllers/recipe_controller'
Below is config.ru file
require "sinatra"
require './app/controllers/recipe_controller'
run RecipeController
my create_recipes file
class CreateRecipes < ActiveRecord::Migration[7.0]
def change
create_table :recipes do |t|
t.string :name
t.text :description
t.boolean :completed
t.timestamps
end
end
Running tests on Rails on the built Sample App (Michael Hartl Rails 5), When running tests I get the above error, which suggests it can't find the table 'users', it's available in my db migrate folder and also listed in the development.sqlite3 file, So not sure what the issue is
Tried the recommended fixes running rake db:test:prepare, rails db:migrate:reset testing to see if User.new(name: 'foo') creates a user neither have fixed the problem and the latter creates fine in the console so can't understand why it can't find the table
_create_users.rb
def change
create_table :users do |t|
t.string :name
t.string :email
t.timestamps
end
end
end
tests to run errors run when attempting 'rails test:mailers' and more when using 'rails test'
db:migrate
SQLite
It's important to remember that each environment in Rails has its own database. Just because your application is working when you're doing development (RAILS_ENV=development), it doesn't mean the database is there when running tests (RAILS_ENV=test).
You may simply need to prepare your test database (create it and migrate it):
# Drop any test DB you already have
bundle exec rake db:drop RAILS_ENV=test
# Create a clean fresh one
bundle exec rake db:create RAILS_ENV=test
# Import the Schema from your schema.rb, rather than run all migrations
bundle exec rake db:schema:load RAILS_ENV=test
If you do the above and then run your tests, they should work as expected.
I am new to Ruby and Sinatra, and I am attempting to finish this tutorial: http://www.sitepoint.com/just-do-it-learn-sinatra-iv/
At the end of the tutorial, before deployment, the tutorial says "Before we move on to deploying the app, we should just check that everything is running fine on our local machine. This is done in a different way now that we have a rackup file." It then instructs the student to enter "rackup" at the command line. When I do so, then go to the 9292 local port specified in my browser I get the error:
DataObjects::ConnectionError at / file is encrypted or is not a database
But when I run my application by typing "ruby main.rb" in the same directory, the app works fine in my browser. Is the tutorial wrong? Am I fine to just deploy my app to Heroku as is? Or do I need to get it working using the rackup command?
I am using sqlite3 1.3.9 and ruby 2.0.0
here is my 'main.rb' file:
require 'sinatra'
require 'data_mapper'
require 'slim'
require 'sass'
DataMapper.setup(:default, 'sqlite3::memory:')
class Task
include DataMapper::Resource
property :id, Serial
property :name, String, :required => true
property :completed_at, DateTime
belongs_to :list
end
class List
include DataMapper::Resource
property :id, Serial
property :name, String, :required => true
has n, :tasks, :constraint => :destroy
end
Task.auto_upgrade!
List.auto_upgrade!
#checks integrty of models
DataMapper.finalize
#For using SASS
get('/styles.css'){ content_type 'text/css', :charset => 'utf-8' ; scss :styles }
get '/' do
#lists = List.all(:order => [:name])
slim :index
end
post '/:id' do
List.get(params[:id]).tasks.create params['task']
redirect to('/')
end
delete '/task/:id' do
Task.get(params[:id]).destroy
redirect to('/')
end
#this adds a button that toggles a checkmark on and off
#so you can check something off your list
put '/task/:id' do
task = Task.get params[:id]
task.completed_at = task.completed_at.nil? ? Time.now : nil
task.save
redirect to('/')
end
post '/new/list' do
List.create params['list']
redirect to('/')
end
delete '/list/:id' do
List.get(params[:id]).destroy
redirect to('/')
end
my config.ru file:
require 'bundler'
Bundler.require
require './main'
DataMapper.setup(:default, ENV['DATABASE_URL'] || "sqlite3://#{Dir.pwd}/development.db")
run Sinatra::Application
and my Gemfile
source :rubygems
gem "sinatra"
gem "datamapper"
gem "slim"
gem "sass"
gem "dm-postgres-adapter", :group => :production
gem "dm-sqlite-adapter", :group => :development
gem 'tilt', '~> 1.4.1'
I also have a config file in a .bundle folder that says
---
BUNDLE_WITHOUT: production
I'm not sure where to start.
My code is already different in a few ways than the final code posted at:
https://github.com/daz4126/Just-Do-It
because I have already had some errors that I had to make workarounds for. Copy pasting the final code doesn't make it work.
Thanks in advance. I have other files I can post, just figured the relevant files were these.
ActiveRecord 3.2.14
I want to use ActiveRecord in a non-Rails Ruby project. I want to have available the rake tasks that are defined by ActiveRecord. How can I do that?
rake db:create # 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)
rake db:drop # Drops the database using DATABASE_URL or the current Rails.env (use db:drop:all to drop all databases)
rake db:fixtures:load # Load fixtures into the current environment's database
rake db:migrate # Migrate the database (options: VERSION=x, VERBOSE=false)
rake db:migrate:status # Display status of migrations
rake db:rollback # Rolls the schema back to the previous version (specify steps w/ STEP=n)
rake db:schema:dump # Create a db/schema.rb file that can be portably used against any DB supported by AR
rake db:schema:load # Load a schema.rb file into the database
rake db:seed # Load the seed data from db/seeds.rb
rake db:setup # Create the database, load the schema, and initialize with the seed data (use db:reset to also drop the db first)
rake db:structure:dump # Dump the database structure to db/structure.sql
rake db:version # Retrieves the current schema version number
The above list is the list of tasks that I want to be able to use on my non-Rails Ruby project that uses ActiveRecord. What do I have to write in my Rakefile?
Thanks in advance
The easiest thing to do is to load the tasks already defined in databases.rake. Here is a GIST of how it was done.
Inspired by this GIST by Drogus
Rakefile.rb
require 'yaml'
require 'logger'
require 'active_record'
include ActiveRecord::Tasks
class Seeder
def initialize(seed_file)
#seed_file = seed_file
end
def load_seed
raise "Seed file '#{#seed_file}' does not exist" unless File.file?(#seed_file)
load #seed_file
end
end
root = File.expand_path '..', __FILE__
DatabaseTasks.env = ENV['ENV'] || 'development'
DatabaseTasks.database_configuration = YAML.load(File.read(File.join(root, 'config/database.yml')))
DatabaseTasks.db_dir = File.join root, 'db'
DatabaseTasks.fixtures_path = File.join root, 'test/fixtures'
DatabaseTasks.migrations_paths = [File.join(root, 'db/migrate')]
DatabaseTasks.seed_loader = Seeder.new File.join root, 'db/seeds.rb'
DatabaseTasks.root = root
task :environment do
ActiveRecord::Base.configurations = DatabaseTasks.database_configuration
ActiveRecord::Base.establish_connection DatabaseTasks.env.to_sym
end
load 'active_record/railties/databases.rake'
You could try the standalone-migrations gem:
https://github.com/thuss/standalone-migrations
For Rails 3.x:
You need to manually create the tasks. As example here is how to add them (this example uses the environment variables like Rails):
namespace :db do
desc "Drop and create the current database"
task :recreate => :environment do
abcs = ActiveRecord::Base.configurations
ActiveRecord::Base.establish_connection(abcs[RAILS_ENV])
ActiveRecord::Base.connection.recreate_database(ActiveRecord::Base.connection.current_database)
end
end
and you'll have the task rake db:recreate available
For Rails 4.x:
If you want to have the ActiveRecord rake tasks available in your ruby app, take a look at the documentation.
Example usage of DatabaseTasks outside Rails could look as such:
include ActiveRecord::Tasks
DatabaseTasks.database_configuration = YAML.load(File.read('my_database_config.yml'))
DatabaseTasks.db_dir = 'db'
# other settings...
DatabaseTasks.create_current('production')
Also you have here an example on how to use ActiveRecord in your ruby aplication.
Create your own!
Reference the Rails one though:
https://github.com/rails/rails/blob/master/activerecord/lib/active_record/railties/databases.rake
Create a Rake Task file. To use Rake, generally you want a tasks folder filled with Rake task files. These files have the ".task" extension.
Study the file to link given.
Take parts of that file, or even the entire contents of the file, and add it to your new Rake task file.
Make sure your Rakefile loads those task files. Your Rakefile should have something like this
-
Dir[File.join(PROJECT_ROOT, 'tasks', '**', '*.rake')].each do |file|
load file
end
I believe you can use the sinatra-activerecord gem even if you're not using Sinatra. I just solved this problem by requiring that gem and then adding
require 'sinatra/activerecord/rake'
to my rakefile.
Once I added that require line the db tasks showed up in my rake -T!
If you are using Sinatra, you can use this gem:
https://github.com/janko-m/sinatra-activerecord
However, if you don't use it either, the source code inside provides a good example on how to implement AR rake tasks.
I have a rakefile.rb in which there is task called add_latest_apps. This task creates some tables in a database if they have not been create using datamapper, scrapes some info from an xml feed and then puts the data in the tables. The problem is that I can't seem to get my rake task to run.
If I use the following command heroku run rake add_latest_apps then I get: rake aborted! no such file to load -- dm-sqlite-adapter which suggests to me that is trying to use the sqlite adapter even though it should be using the postgres adapter. What am I doing wrong?
rakefile.rb:
require 'open-uri'
require 'nokogiri'
require 'awesome_print'
require 'data_mapper'
require 'dm-postgres-adapter'
require 'pg'
task :add_latest_apps do
DataMapper.setup(:default, ENV['DATABASE_URL'] || "sqlite3://#{Dir.pwd}/app.db")
class Company
include DataMapper::Resource
property :id, Serial
property :company_name, String
property :company_id, Text, :unique => true
has n, :apps
end
class App
include DataMapper::Resource
property :id, Serial
property :app_id, Integer
property :bundle_id, Text
property :app_name, Text
property :company_name, Text
property :created_at, DateTime
property :rank, Integer
belongs_to :company
end
DataMapper.finalize.auto_upgrade!
puts 'Database and tables created'
#Get App data from Apple
#Insert apps and companies into database
end
Gemfile:
source :rubygems
gem 'sinatra', '1.1.0'
gem 'thin'
gem 'nokogiri'
gem 'awesome_print'
gem 'data_mapper'
gem 'dm-postgres-adapter'
gem 'pg'
Please help!
You need to set the DATABASE_URL environment variable.
The problem is with the line:
DataMapper.setup(:default, ENV['DATABASE_URL'] || "sqlite3://#{Dir.pwd}/app.db")
Here DataMapper looks for ENV['DATABASE_URL'], and if it isn’t set falls back to "sqlite3://#{Dir.pwd}/app.db", which causes it to try to load dm-sqlite-adapter.
Run heroku config to show your environment vars, it probaby won’t show DATABASE_URL. Check out the Heroku Postgres docs to determine what your URL should be. You may be able to do something like heroku pg:promote HEROKU_POSTGRESQL_GRAY_URL (although you’ll need to check what colour you should use).