Skip to content

rubydevro/typesense_model

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

8 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

TypesenseModel

A Ruby gem that provides seamless Typesense integration for ActiveRecord models with automatic syncing and search capabilities.

Installation

Add to your Gemfile:

gem 'typesense_model'

Or install directly:

$ gem install typesense_model

Configuration

Initialize Typesense connection in your Rails application:

# config/initializers/typesense.rb
TypesenseModel.configure do |config|
  config.api_key = 'your_api_key'
  config.host = 'localhost'
  config.port = 8108
  config.protocol = 'http'
end

ActiveRecord Integration

The gem automatically extends ActiveRecord models with Typesense capabilities. Simply add uses_typesense to any model:

class Product < ApplicationRecord
  uses_typesense collection: 'products' do
    field :id, :string
    field :name, :string
    field :description, :string, optional: true, index: false
    field :price, :float, sort: true
    field :categories, "string[]", optional: true, facet: true
    field :tags, "string[]", optional: true, facet: true
    field :brand, :string, facet: true
    field :in_stock, :bool, facet: true
    field :created_at, :int64, sort: true
    field :updated_at, :int64, sort: true
  end

  # Optional: Custom JSON serialization for Typesense
  def as_json_typesense
    {
      id: id,
      name: name,
      description: description,
      price: price,
      categories: categories,
      tags: tags,
      brand: brand,
      in_stock: in_stock,
      created_at: created_at.to_i,
      updated_at: updated_at.to_i
    }
  end
end

Features

Automatic Syncing

When you save or destroy ActiveRecord records, they automatically sync to Typesense:

# Create a product - automatically synced to Typesense
product = Product.create!(
  name: "iPhone 15",
  price: 999.99,
  categories: ["Electronics", "Phones"],
  brand: "Apple",
  in_stock: true
)

# Update a product - automatically synced to Typesense
product.update!(price: 899.99)

# Destroy a product - automatically removed from Typesense
product.destroy!

Search Capabilities

Search your ActiveRecord models using Typesense:

# Basic search
results = Product.search("iPhone")

# Advanced search with filters and sorting
results = Product.search("smartphone", 
  filter_by: "brand:Apple && price:< 1000",
  sort_by: "price:asc",
  per_page: 20,
  page: 1
)

# Search with facets
results = Product.search("phone")
results.facet_values("brand")  # Get brand facet counts
results.facet_values("categories")  # Get category facet counts

Access Typesense Documents

Get the Typesense document for any ActiveRecord instance:

product = Product.find(123)
typesense_doc = product.typesense_model
# Returns a TypesenseModel::Base instance with the Typesense document data

Schema Options

Field options available in the schema definition:

  • optional: true - Field is optional
  • index: false - Field is not indexed (not searchable)
  • facet: true - Field can be used for faceted search
  • sort: true - Field can be used for sorting
  • default_sort: true - Field is the default sorting field

Custom JSON Serialization

You can customize how your model data is serialized for Typesense:

class Product < ApplicationRecord
  uses_typesense collection: 'products', model_json: :to_typesense_hash do
    # schema definition
  end

  def to_typesense_hash
    {
      id: id,
      name: name,
      price: price,
      # Add computed fields
      searchable_text: "#{name} #{description} #{brand}".downcase,
      price_range: case price
        when 0..100 then "budget"
        when 101..500 then "mid-range"
        else "premium"
      end
    }
  end
end

Or use a Proc for dynamic serialization:

class Product < ApplicationRecord
  uses_typesense collection: 'products', 
    model_json: ->(record) { record.as_json.merge(computed_field: record.compute_something) } do
    # schema definition
  end
end

Collection Management

Create and manage Typesense collections:

# Create the collection in Typesense
Product.search("") # This will create the collection if it doesn't exist

# Or explicitly create/update
proxy = TypesenseModel::ActiveRecordExtension::TypesenseProxy.for(Product)
proxy.create_collection
proxy.update_collection
proxy.delete_collection

Import Existing Data

Import existing ActiveRecord records to Typesense without N+1 queries:

# Basic import (default batch_size: 1000)
results = Product.import_all_to_typesense

# With preloads to avoid N+1
results = Product.import_all_to_typesense(preloads: [:brand, :images])

# With custom transformer and options
results = Product.import_all_to_typesense(
  preloads: { variants: [:prices, :stock_items] },
  transform: :to_typesense_hash,
  batch_size: 2000,
  import_options: { action: 'upsert' }
)

# results => { success: 500, failed: 0, errors: [...] }

License

Available as open source under the MIT License. Copyright (c) 2025 Ruby Dev SRL

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages