-
Notifications
You must be signed in to change notification settings - Fork 123
Open
Labels
enhancementNew feature or requestNew feature or request
Milestone
Description
Summary
Provide first-class Rails integration via either a classifier-rails gem or a Rails generator that sets up ActiveRecord-based storage automatically.
Motivation
After #90 ships, Rails users who want database persistence will need to:
- Create a migration manually
- Create a model manually
- Write their own
ARStorageclass - Configure it in an initializer
This is fine for power users, but Rails is about convention over configuration. We should make the common case trivial:
rails generate classifier:install
rails db:migrate
# Done. It just works.Option A: Rails Generator (Simpler)
Ship a generator in the main gem that's only loaded when Rails is detected.
$ rails generate classifier:install
create db/migrate/20250101000000_create_trained_classifiers.rb
create app/models/trained_classifier.rb
create config/initializers/classifier.rbGenerated migration:
class CreateTrainedClassifiers < ActiveRecord::Migration[7.0]
def change
create_table :trained_classifiers do |t|
t.string :key, null: false, index: { unique: true }
t.text :data, null: false
t.timestamps
end
end
endGenerated model:
class TrainedClassifier < ApplicationRecord
validates :key, presence: true, uniqueness: true
validates :data, presence: true
endGenerated storage class:
# app/models/classifier_storage.rb
class ClassifierStorage < Classifier::Storage::Base
def initialize(key:)
@key = key
end
def write(data)
TrainedClassifier.upsert({ key: @key, data: data }, unique_by: :key)
end
def read
TrainedClassifier.find_by(key: @key)&.data
end
def delete
TrainedClassifier.where(key: @key).delete_all
end
def exists?
TrainedClassifier.exists?(key: @key)
end
endGenerated initializer:
# config/initializers/classifier.rb
# Classifier is ready to use with ActiveRecord storage:
#
# bayes = Classifier::Bayes.new('Spam', 'Ham')
# bayes.storage = ClassifierStorage.new(key: "spam_filter")
# bayes.save
#
# Or create a helper method in ApplicationController:
#
# def spam_classifier
# @spam_classifier ||= Classifier::Bayes.load(
# storage: ClassifierStorage.new(key: "spam_filter")
# )
# endOption B: Separate classifier-rails Gem
Create a classifier-rails gem that:
- Provides the generator
- Ships
Classifier::Storage::ActiveRecordbuilt-in - Adds Rails-specific conveniences
# Gemfile
gem 'classifier-reborn'
gem 'classifier-rails'# This class ships with the gem
bayes.storage = Classifier::Storage::ActiveRecord.new(key: "spam_filter")Recommendation
Start with Option A (generator in main gem). It's simpler, no new gem to maintain, and covers 90% of Rails use cases.
If demand grows, extract to classifier-rails later.
Usage After Install
# Train and save
bayes = Classifier::Bayes.new('Spam', 'Ham')
bayes.storage = ClassifierStorage.new(key: "email_filter")
bayes.train_spam("Buy now!")
bayes.save
# Load in another request
bayes = Classifier::Bayes.load(storage: ClassifierStorage.new(key: "email_filter"))
bayes.classify("Free money") # => "Spam"Acceptance Criteria
-
rails generate classifier:installcreates migration, model, storage class, initializer - Generator only available when Rails is loaded
- Generated code follows Rails conventions
- Works with Rails 6.1+
- Documentation in README
Dependencies
- Requires Add pluggable persistence backends with ActiveRecord-style configuration #90 (pluggable storage) to be completed first
Non-Goals
- ❌ Auto-configuring storage globally (explicit is better)
- ❌ ActiveRecord adapter shipped in core gem (users own generated code)
- ❌ Supporting non-ActiveRecord Rails ORMs (Sequel, ROM, etc.)
Metadata
Metadata
Assignees
Labels
enhancementNew feature or requestNew feature or request