我正在编写一个gem,它是一个命令行工具,并试图弄清楚如何让ActiveRecord在其中运行以管理数据库。
我从一个有效的ActiveRecord项目开始(Flatiron新手训练营课程),分别构建了一个gem(bundle gem gemname
),然后手工将gem的所有文件结构复制并改编到AR项目中。请注意,我没有使用Rails或任何其他可能包装ActiveRecord的框架。
我已尽力进行了设置,但似乎无法弄清楚最后一英里:我无法对数据库进行任何操作。
$ rake db:create
rake aborted!
ActiveRecord::AdapterNotSpecified: 'development' database is not configured. Available: []
$ rake db:migrate
rake aborted!
ActiveRecord::ConnectionNotEstablished: No connection pool with 'primary' found.
以下是该项目中的一些相关内容:
# FILE STRUCTURE
LearnManager
| .travis.yml
| Gemfile.lock
| Rakefile
| LICENSE.md
| Gemfile
| CONTRIBUTING.md
| .rspec
| .gitignore
| .git
| app
| | models
| | | unit.rb
| | | topic.rb
| | | lesson.rb
| bin
| | setup
| | console
| config
| | db
| | | schema.rb
| | | learnmanager-development.db
| | migrate
| | | 20190210190844_create_lessons
| lib
| | LearnManager.rb
| | LearnManager
| | | version.rb
| | support
| | | db_registry.rb
| | | connection_adapter.rb
| spec
| | spec_helper.rb
| LearnManager.gemspec
# config/environment.rb
require 'bundler/setup'
Bundler.require
require 'rake'
require 'active_record'
require 'yaml/store'
require 'ostruct'
require 'date'
DBNAME = "learnmanager"
Dir[File.join(File.dirname(__FILE__), "../app/models", "*.rb")].each {|f| require f}
Dir[File.join(File.dirname(__FILE__), "../lib/support", "*.rb")].each {|f| require f}
DBRegistry[ENV["ACTIVE_RECORD_ENV"]].connect!
DB = ActiveRecord::Base.connection
if ENV["ACTIVE_RECORD_ENV"] == "test"
ActiveRecord::Migration.verbose = false
end
# db/migrate/20190210190844_create_lessons
class CreateLessons < ActiveRecord::Migration[5.2]
def change
create_table :lessons do |t|
t.string :title
t.belongs_to :unit, index: true
end
end
end
# app/models/lesson.rb
class Lesson < ActiveRecord::Base
belongs_to :unit
end
# db/schema.rb
ActiveRecord::Schema.define(version: 0) do
create_table :topics, force: true do |t|
t.string :name
end
create_table :units, force: true do |t|
t.string :name
t.belongs_to :topic, index: true
end
create_table :lessons, force: true do |t|
t.string :name
t.belongs_to :unit, index: true
end
end
# lib/support/connection_adapter.rb
class ConnectionAdapter
attr_reader :adapter, :database
def initialize(database, adapter="sqlite3")
@adapter = adapter
@database = database
end
def connect!
ActiveRecord::Base.establish_connection(
:adapter => self.adapter,
:database => self.database
)
end
end
# lib/support/db_registry.rb
require_relative "./connection_adapter.rb"
DBRegistry ||= OpenStruct.new(test: ConnectionAdapter.new("db/#{DBNAME}-test.db"),
development: ConnectionAdapter.new("db/#{DBNAME}-development.db"),
production: ConnectionAdapter.new("db/#{DBNAME}-production.db")
)
# Rakefile
require 'bundler/setup'
Bundler.require
require 'active_record'
require 'sinatra/activerecord/rake'
require 'pry'
task :environment do
ENV["ACTIVE_RECORD_ENV"] ||= "development"
require_relative './config/environment'
end
include ActiveRecord::Tasks
DatabaseTasks.db_dir = 'db'
DatabaseTasks.migrations_paths = 'db/migrate'
seed_loader = Class.new do
def load_seed
load "#{ActiveRecord::Tasks::DatabaseTasks.db_dir}/seeds.rb"
end
end
DatabaseTasks.seed_loader = seed_loader.new
load 'active_record/railties/databases.rake'
task :console => :environment do
Pry.start
end
# --------- FROM GEM BUILD ---------
require "bundler/gem_tasks"
require "rspec/core/rake_task"
RSpec::Core::RakeTask.new(:spec)
# LearnManager.gemspec (excerpts)
lib = File.expand_path("../lib", __FILE__)
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
require "LearnManager/version"
Gem::Specification.new do |spec|
spec.add_development_dependency "bundler", "~> 1.16"
spec.add_development_dependency "rake", "~> 10.0"
spec.add_development_dependency "rspec", "~> 3.0"
spec.add_development_dependency "pry"
spec.add_development_dependency "pry-byebug"
spec.add_development_dependency "pry-rescue"
spec.add_dependency "activerecord"
spec.add_dependency "sqlite3", "~> 1.3.6"
spec.add_dependency "database_cleaner"
spec.add_dependency "sinatra-activerecord"
end
有人知道我如何才能使它真正起作用吗?
答案 0 :(得分:1)
我也这样做,但是我不使用耙子,我只使用纯红宝石。这是我项目中的两种方法,我在Rails之外使用Active Record。
基本上,我连接到数据库,检查表是否存在,如果不存在,则加载架构文件。加载架构后,我将使用常规ActiveRecord方法填充数据库并执行查询。我不需要进行迁移,所以我没有尝试过
class MyDb
attr_reader :file_name
def initialize(file_name)
@file_name = file_name
end
def connect()
@connection = ActiveRecord::Base.establish_connection(
adapter: "sqlite3",
database: filename,
)
create_tables unless tables_exists?
end
def tables_exists?
ActiveRecord::Base.connection.tables.size > 0
end
def create_tables()
puts "database is empty...\ncreating tables"
path_to_current_file = File.expand_path(File.dirname(__FILE__))
load("#{path_to_current_file}/ar_support/schema.rb")
end
end
然后从顶级红宝石脚本中执行类似的操作。
my_db = MyDb.new("mydb.sqlite3")
my_db.connect
这是我也使用的一个示例schema.rb文件。
ActiveRecord::Schema.define(version: 20180430230151) do
create_table "chips", force: :cascade do |t|
t.string "name"
end
create_table "macros", force: :cascade do |t|
t.string "name"
t.integer "chip_id"
t.index ["chip_id"], name: "index_macros_on_chip_id"
end
create_table "measurements", force: :cascade do |t|
t.string "name"
t.float "value"
t.string "group_name"
t.string "plot"
t.boolean "test_result"
t.string "test_expression"
t.integer "run_id"
t.index ["run_id"], name: "index_measurements_on_run_id"
end
create_table "runs", force: :cascade do |t|
t.string "source_dir"
t.string "source_file"
t.integer "macro_id"
t.string "corner_name"
t.string "sim_type"
t.string "netlist_type"
t.index ["macro_id"], name: "index_runs_on_macro_id"
end
create_table "tags", force: :cascade do |t|
t.string "name"
t.integer "run_id"
t.string "value"
t.index ["run_id"], name: "index_tags_on_run_id"
end
end
开始使用数据库。 (您还需要定义模型)
chip = Chip.find_or_create_by(name: e.chip)
macro = chip.macros.find_or_create_by(name: e.macro)