This repository was originally created to satisfy my need for a kind of boilerplate using Glimmer DSL with ActiveRecord as an ORM over a sqlite3 database. At that time, I couldn't find any resources on it. Since then, Andy Maleh, OSS Author of Glimmer, reached out to me about his post, Using ActiveRecord with SQLite DB in a JRuby Desktop App. I decided to put together a tutorial to extend this idea further, including other migration tasks from ActiveRecord::Tasks::DatabaseTask, and an ability to run rake db:seed using the SeedLoader.
If you'd like to use this repository, just follow Setup. Otherwise, follow the ALTERNATIVE APPROACH.
- Clone repository
- Install dependencies:
bundle install - Prepare database:
rake db:prepare - Run app:
glimmer run
Without using this repository, just follow along with this tutorial.
- Install Glimmer
- Scaffold a Glimmer demo app
- Commit remaining scaffolding
- Add dependencies
- Install dependencies
- Add db directory
- Add migration for contacts table
- Add database configuration
- Add a SQLite database with ActiveRecord
- Integrate DatabaseTasks with SeedLoader
- Add rake tasks for ActiveRecord migrations
- Wire up ActiveRecord tasks in Rakefile
- Verify rake tasks
- Prepare database
- Add Contact model
- Add seed data
- Import seed data
- Update demo view
- Run demo app
- Troubleshooting
See instructions at glimmer-dsl-libui
glimmer "scaffold[demo]" cd demo This step is optional.
Glimmer makes an initial git commit and leaves a dirty tree, so to clean it up...
git add . git commit -m "Add remaining scaffolding" after gem 'glimmer-dsl-libui' line
# Gemfile gem 'activerecord', '~> 7.1', '>= 7.1.3.4' gem 'sqlite3', '~> 1.4', force_ruby_platform: truebundle install mkdir -p db/migrate touch db/migrate/20240708135100_create_contacts.rb # db/migrate/20240708135100_create_contacts.rb require 'active_record' class CreateContacts < ActiveRecord::Migration[7.1] def change create_table :contacts do |t| t.string :first_name t.string :last_name t.string :email t.string :phone t.string :street t.string :city t.string :state_or_province t.string :zip_or_postal_code t.string :country end end endmkdir config touch config/database.yml # config/database.yml default: &default adapter: sqlite3 pool: 5 timeout: 5000 development: <<: *default database: db/demo.sqlite3 test: <<: *default database: db/test.sqlite3touch db/config.rb # db/config.rb class Demo module DB module Config def root File.expand_path('../..', __FILE__) end def file File.join(root, "config/database.yml") end def yaml # aliases: true fixes Psych::AliasesNotEnabled exception YAML.load_file(file, aliases: true) end def env ENV['ENV'] || 'development' end end end endtouch db/connection.rb # db/connection.rb require 'active_record' require_relative './config' include Demo::DB::Config ActiveRecord::Base.configurations = Demo::DB::Config::yaml ActiveRecord::Base.establish_connection(Demo::DB::Config::env.to_sym) ActiveRecord::Base.logger = ActiveSupport::Logger.new(STDOUT)mkdir support touch support/active_record_rake_tasks.rb # support/active_record_rake_tasks.rb require_relative '../db/connection' include ActiveRecord::Tasks root = Demo::DB::Config::root DatabaseTasks.root = root DatabaseTasks.db_dir = File.join(root, 'db') DatabaseTasks.migrations_paths = [File.join(root, 'db/migrate')] DatabaseTasks.database_configuration = Demo::DB::Config::yaml # The SeedLoader is Optional, if you don't want/need seeds you can skip setting it class SeedLoader def initialize(seed_file) @seed_file = seed_file end def load_seed load @seed_file if File.exist?(@seed_file) end end DatabaseTasks.seed_loader = SeedLoader.new(File.join(root, 'db/seeds.rb')) DatabaseTasks.env = Demo::DB::Config::env load 'active_record/railties/databases.rake'# Rakefile require './support/active_record_rake_tasks'rake -T # Rakefile Rake::Task.define_task(:environment)rake db:prepare touch app/demo/model/contact.rb # app/demo/model/contact.rb class Contact < ActiveRecord::Base endtouch db/seeds.rb touch db/models.rb # db/models.rb model_dir = File.expand_path('../../app/demo/model', __FILE__) Dir.glob(File.join(model_dir, '**', '*.rb')).each { |model| require model }# db/seeds.rb require 'active_record' require_relative './connection' require_relative "./models" Contact.create(first_name: 'Chip', last_name: 'Castle', email: 'chip@chipcastle.com', phone: '555-555-5555', street: 'Any street', city: 'Inlet Beach', state_or_province: 'FL', zip_or_postal_code: '55555', country: 'US') rake db:seed At the top of the file, replace the require 'demo/model/greeting' with:
# app/demo/view/demo.rb require 'demo/model/contact'Inside the before_body block, replace @greeting = Model::Greeting.new with:
@contact = Contact.firstInside def launch method (after margined true line), remove the reference to the @greeting form entry and add the following code to verify ActiveRecord:
vertical_box { form { stretchy false entry { label 'First name' text <=> [@contact, :first_name] } entry { label 'Last name' text <=> [@contact, :last_name] } entry { label 'Email' text <=> [@contact, :email] } entry { label 'Phone' text <=> [@contact, :phone] } entry { label 'Street address' text <=> [@contact, :street] } entry { label 'City' text <=> [@contact, :city] } entry { label 'State/Province' text <=> [@contact, :state_or_province] } entry { label 'Zip/Postal code' text <=> [@contact, :zip_or_postal_code] } entry { label 'Country' text <=> [@contact, :country] } } } glimmer run - If you encounter a
Don't know how to build task environmenterror, try adding this to the bottom of yourRakefile:
# Rakefile Rake::Task.define_task(:environment)- When an ActiveRecord::EnvironmentMismatchError exception is raised, run this from the shell:
rake db:environment:set ENV=development- Running
rake db:versionraises anNameError: uninitialized constant Rails (NameError)exception, which can be fixed with this hack (open to other suggestions, but I gotta move on.)
# Rakefile class Rails def env ENV['ENV'] || 'development' end endCopyright (c) 2024 Chip Castle. See LICENSE for further details.
