こちらの記事の続きです。
Sinatraでrakeファイルに記述したActive Recordを使用し、bundle exec rake~
でrakeファイル記述した内容を実行しようとした際に出たエラーの内容に関する記事です。
エラー内容は
cannot load such file -- sinatra/activerecord
という内容で、ログに表現されている内容はとても簡単で、sinatra/activerecordなんてねーよ
って意味です。けっこうな量の記事通りにsinatraのアプリを組んでも、このエラーが出るので、自分のPCの環境がよくないのかなとも思っています。ちなみにWin10を使用しています。
*参考
https://railsgirls-bne.github.io/sinatra-app-guide
https://github.com/janko/sinatra-activerecord
Gemfileの作成
Gemfile
source 'https://rubygems.org'
gem 'sqlite3'
gem 'rake'
gem 'sinatra'
gem 'sinatra-activerecord', path: ".."
gem 'activerecord'
gem 'pry'
gem 'pry-byebug'
bundle install
しましょう。
Rakefileの作成
Rakefile
require 'sinatra/activerecord'
require 'sinatra/activerecord/rake'
namespace :db do
task :load_config do
require "./app"
end
end
Rakefileの内容です。
sinatraフォルダの作成
sinatra
フォルダを作りましょう!
その配下にactiverecord.rb
ファイルを作成します。
require 'sinatra/base'
require 'active_record'
require 'active_support/core_ext/hash/keys'
require 'logger'
require 'pathname'
require 'yaml'
require 'erb'
module Sinatra
module ActiveRecordHelper
def database
settings.database
end
end
module ActiveRecordExtension
def self.registered(app)
if ENV['DATABASE_URL']
app.set :database, ENV['DATABASE_URL']
elsif File.exist?("#{Dir.pwd}/config/database.yml")
app.set :database_file, "#{Dir.pwd}/config/database.yml"
end
unless defined?(Rake) || [:test, :production].include?(app.settings.environment)
ActiveRecord::Base.logger = Logger.new(STDOUT)
end
app.helpers ActiveRecordHelper
# re-connect if database connection dropped (Rails 3 only)
app.before { ActiveRecord::Base.verify_active_connections! if ActiveRecord::Base.respond_to?(:verify_active_connections!) }
app.after { ActiveRecord::Base.clear_active_connections! }
end
def database_file=(path)
path = File.join(root, path) if Pathname(path).relative? and root
spec = YAML.load(ERB.new(File.read(path)).result) || {}
set :database, spec
end
def database=(spec)
if spec.is_a?(Hash) and spec.symbolize_keys[environment.to_sym]
ActiveRecord::Base.configurations = spec.stringify_keys
ActiveRecord::Base.establish_connection(environment.to_sym)
elsif spec.is_a?(Hash)
ActiveRecord::Base.configurations[environment.to_s] = spec.stringify_keys
ActiveRecord::Base.establish_connection(spec.stringify_keys)
else
ActiveRecord::Base.establish_connection(spec)
ActiveRecord::Base.configurations ||= {}
ActiveRecord::Base.configurations[environment.to_s] = ActiveRecord::ConnectionAdapters::ConnectionSpecification::ConnectionUrlResolver.new(spec).to_hash
end
end
def database
ActiveRecord::Base
end
end
register ActiveRecordExtension
end
そして、sinatra
フォルダ配下にactiverecord
フォルダを作成します。
sinatra/activerecord
の配下にrake.rb
と、tasks.rake
を作成します。
load "active_record/railties/databases.rake"
require "sinatra/activerecord/rake/activerecord_#{ActiveRecord::VERSION::MAJOR}"
load "sinatra/activerecord/tasks.rake"
ActiveRecord::Base.logger = nil
require "active_support/core_ext/string/strip"
require "pathname"
require "fileutils"
namespace :db do
desc "Create a migration (parameters: NAME, VERSION)"
task :create_migration do
unless ENV["NAME"]
puts "No NAME specified. Example usage: `rake db:create_migration NAME=create_users`"
exit
end
name = ENV["NAME"]
version = ENV["VERSION"] || Time.now.utc.strftime("%Y%m%d%H%M%S")
ActiveRecord::Migrator.migrations_paths.each do |directory|
next unless File.exist?(directory)
migration_files = Pathname(directory).children
if duplicate = migration_files.find { |path| path.basename.to_s.include?(name) }
puts "Another migration is already named \"#{name}\": #{duplicate}."
exit
end
end
filename = "#{version}_#{name}.rb"
dirname = ActiveRecord::Migrator.migrations_paths.first
path = File.join(dirname, filename)
ar_maj = ActiveRecord::VERSION::MAJOR
ar_min = ActiveRecord::VERSION::MINOR
base = "ActiveRecord::Migration"
base += "[#{ar_maj}.#{ar_min}]" if ar_maj >= 5
FileUtils.mkdir_p(dirname)
File.write path, <<-MIGRATION.strip_heredoc
class #{name.camelize} < #{base}
def change
end
end
MIGRATION
puts path
end
end
# The `db:create` and `db:drop` command won't work with a DATABASE_URL because
# the `db:load_config` command tries to connect to the DATABASE_URL, which either
# doesn't exist or isn't able to drop the database. Ignore loading the configs for
# these tasks if a `DATABASE_URL` is present.
if ENV.has_key? "DATABASE_URL"
Rake::Task["db:create"].prerequisites.delete("load_config")
Rake::Task["db:drop"].prerequisites.delete("load_config")
end
sinatra/activerecord
の配下に、rake
フォルダを作成します。
rake
フォルダの配下にactiverecord_"Active Recordのver".rb
を作成します。
私の場合はActive Record6なので、activerecord_6.rb
になります。
seed_loader = Class.new do
def load_seed
load "#{ActiveRecord::Tasks::DatabaseTasks.db_dir}/seeds.rb"
end
end
ActiveRecord::Tasks::DatabaseTasks.tap do |config|
config.root = Rake.application.original_dir
config.env = ENV["RACK_ENV"] || "development"
config.db_dir = "db"
config.migrations_paths = ["db/migrate"]
config.fixtures_path = "test/fixtures"
config.seed_loader = seed_loader.new
config.database_configuration = ActiveRecord::Base.configurations
end
# db:load_config can be overriden manually
Rake::Task["db:seed"].enhance(["db:load_config"])
Rake::Task["db:load_config"].clear
# define Rails' tasks as no-op
Rake::Task.define_task("db:environment")
Rake::Task["db:test:deprecated"].clear if Rake::Task.task_defined?("db:test:deprecated")
これでsinatra
フォルダの内容は出来上がりました。
databaseの設定
config
フォルダを作成し、その配下にdatabase.yml
を作成します。
development:
adapter: sqlite3
database: db/development.sqlite3
test:
adapter: sqlite3
database: db/test.sqlite3
これで基本的な設定は完成です。
bundle exec rake -T
コマンドで、使用できるタスクが表示されるはずです。
rake db:create # Creates the database from DATABASE_URL or con...
rake db:create_migration # Create a migration (parameters: NAME, VERSION)
rake db:drop # Drops the database from DATABASE_URL or confi...
rake db:environment:set # Set the environment value for the database
rake db:fixtures:load # Loads fixtures into the current environment's...
rake db:migrate # Migrate the database (options: VERSION=x, VER...
rake db:migrate:status # Display status of migrations
rake db:prepare # Runs setup if database does not exist, or run...
rake db:rollback # Rolls the schema back to the previous version...
rake db:schema:cache:clear # Clears a db/schema_cache.yml file
rake db:schema:cache:dump # Creates a db/schema_cache.yml file
rake db:schema:dump # Creates a db/schema.rb file that is portable ...
rake db:schema:load # Loads a schema.rb file into the database
rake db:seed # Loads the seed data from db/seeds.rb
rake db:seed:replant # Truncates tables of each database for current...
rake db:setup # Creates the database, loads the schema, and i...
rake db:structure:dump # Dumps the database structure to db/structure.sql
rake db:structure:load # Recreates the databases from the structure.sq...
rake db:version # Retrieves the current schema version number
マイグレーションファイルの作成
bundle exec rake db:create_migration NAME=create_ideas
で、マイグレーションファイルの作成を行います。
20190823054856_create_ideas.rb
のように、日付入りのファイルが出来上がると思います。
class CreateIdeas < ActiveRecord::Migration[6.0]
def change
create_table :ideas do |t|
t.string :name
t.text :description
t.string :picture
t.timestamps null: false
end
end
end
出来上がったマイグレーションファイルに修正を加えます。
特に、class CreateIdeas < ActiveRecord::Migration[6.0]
の[6.0]
を忘れないようにしましょう!
最後にbundle exec rake db:migrate
でマイグレーションを実行し、完了です。
まとめ
ここまで調べるのに長くかかりました。。。
でも、調べ方が上手くなったのでよかったです!