Skip to content

chip/glimmer_dsl_with_active_record

Repository files navigation

Example Glimmer DSL GUI app using ActiveRecord

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.

Demo

Setup

  1. Clone repository
  2. Install dependencies: bundle install
  3. Prepare database: rake db:prepare
  4. Run app: glimmer run

ALTERNATIVE APPROACH

Without using this repository, just follow along with this tutorial.

Table of Contents

Install Glimmer

See instructions at glimmer-dsl-libui

Scaffold a Glimmer demo app

glimmer "scaffold[demo]" cd demo 

Commit remaining scaffolding

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" 

Add dependencies

after gem 'glimmer-dsl-libui' line

# Gemfile gem 'activerecord', '~> 7.1', '>= 7.1.3.4' gem 'sqlite3', '~> 1.4', force_ruby_platform: true

Install dependencies

bundle install 

Add db directory

mkdir -p db/migrate 

Add migration for contacts table

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 end

Add database configuration

mkdir 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.sqlite3

Add a SQLite database with ActiveRecord

Add shared methods for database access

touch 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 end

Add database connection

touch 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)

Integrate DatabaseTasks with SeedLoader

mkdir support touch support/active_record_rake_tasks.rb 

Add rake tasks for ActiveRecord migrations

# 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'

Wire up ActiveRecord tasks in Rakefile

# Rakefile require './support/active_record_rake_tasks'

Verify rake tasks

rake -T 

Add fix for "Don't know how to build task 'environment'" error

# Rakefile Rake::Task.define_task(:environment)

Prepare database

rake db:prepare 

Add Contact model

touch app/demo/model/contact.rb 
# app/demo/model/contact.rb class Contact < ActiveRecord::Base end

Add seed data

touch 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')

Import seed data

 rake db:seed 

Update demo view

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.first

Inside 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] } } }

Run demo app

 glimmer run 

Troubleshooting

  1. If you encounter a Don't know how to build task environment error, try adding this to the bottom of your Rakefile:
# Rakefile Rake::Task.define_task(:environment)
  1. When an ActiveRecord::EnvironmentMismatchError exception is raised, run this from the shell:
 rake db:environment:set ENV=development
  1. Running rake db:version raises an NameError: 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 end

Copyright

Copyright (c) 2024 Chip Castle. See LICENSE for further details.

About

Example Glimmer DSL GUI app using ActiveRecord

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages