SimplyBased 0.1.0 — Couchbase-native ActiveModel ORM

A from-scratch fork of simply_couch's model layer that runs on Couchbase
natively: `include SimplyBased::Model` instead of `include SimplyCouch::Model`.

- SimplyBased::Store replaces the CouchDB layer: KV documents, N1QL/SQL++
  finders + lazily-created GSIs, CAS mapped onto _rev. No design documents or
  JavaScript map/reduce — the hand-written association views become N1QL
  (belongs_to/has_many/has_one scalar FK; habtm via ANY ... SATISFIES + array
  index, or KV multi-get on the storing side).
- Redis replacements on the same cluster: Counter (atomic increment/decrement),
  Cache (ActiveSupport::Cache::Store over KV+TTL, drop-in Rails.cache/ActiveJob),
  Lock (insert-if-absent + TTL + CAS-checked release).
- Runs the simply_couch test suite against live Couchbase: 378/432 applicable
  examples green (CouchDB-mechanic specs tagged :couchdb_only and excluded).
- Remaining: ancestry (tree) + embedded_in reverse-lookups (recursive/embedded
  N1QL) and a few pagination/lifecycle edges.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
GregandClaude Opus 4.8 committed 2026-06-20 13:58:47 -05:00
commit 86299b8827
84 files changed
+9904

No files matched your search

+354
View File
@@ -0,0 +1,354 @@
class User
include SimplyBased::Model
validates_presence_of :title
property :name
property :title
property :homepage
has_many :posts
has_many :strict_posts
has_many :hemorrhoids
has_many :pains, through: :hemorrhoids
has_many :docs, class_name: "Document", foreign_key: "editor_id"
view :by_name_and_created_at, key: [:name, :created_at]
end
class Post
include SimplyBased::Model
belongs_to :user
has_many_embedded :embedded_comments
view :by_user_id, key: :user_id
end
class EmbeddedComment
include SimplyBased::Model
property :body
is_embedded_in :post
belongs_to :strict_post
end
class Page
include SimplyBased::Model
property :categories, type: Array
validates_containment_of :categories, in: %w[one two three]
end
class Directory
include SimplyBased::Model
property :name
property :make_invalid
has_ancestry
validate :check_if_valid
private
def check_if_valid
errors.add(:make_invalid, :invalid) if make_invalid.present?
end
end
class NamespacedDirectory
include SimplyBased::Model
property :name
property :locale
has_ancestry by_property: :locale
end
class StrictPost
include SimplyBased::Model
belongs_to :user
validates_presence_of :user
has_many :embedded_comments
end
class Comment
include SimplyBased::Model
total_pages_method 'total_pages_modified'
current_page_method 'current_page_modified'
num_pages_method 'num_pages_modified'
per_page_method 'per_page_modified'
belongs_to :user
belongs_to :network
end
class Category
include SimplyBased::Model
property :name
property :alias
property :parent
validates_inclusion_of :name, in: ["food", "drinks", "party"], allow_blank: true
end
class Document
include SimplyBased::Model
belongs_to :author, class_name: "User"
belongs_to :editor, class_name: "User"
end
class Tag
include SimplyBased::Model
belongs_to :category
property :name
end
class Instance
include SimplyBased::Model
has_one :identity
end
class Identity
include SimplyBased::Model
belongs_to :instance
belongs_to :magazine
end
class Magazine
include SimplyBased::Model
has_one :identity, dependent: :destroy
end
class UniqueUser
include SimplyBased::Model
property :name
validates_uniqueness_of :name
end
class UniqueUserWithAView
include SimplyBased::Model
view :by_name, key: :email
property :name
validates_uniqueness_of :name
end
class CountMe
include SimplyBased::Model
property :title
end
class DontCountMe
include SimplyBased::Model
property :title
end
class Journal
include SimplyBased::Model
has_many :memberships, dependent: :destroy
has_many :readers, through: :memberships, dependent: :destroy
property :foo
end
class Reader
include SimplyBased::Model
has_many :memberships, dependent: :destroy
has_many :journals, through: :memberships
end
class Membership
include SimplyBased::Model
belongs_to :reader
belongs_to :journal
end
class Callbacker
include SimplyBased::Model
property :name
property :raise_on_save, type: :boolean, default: false
property :with_validation_error, type: :boolean, default: false
property :counter, type: Integer, default: 0
before_save ->{ self.counter += 1 }
after_save :raise_error_after_save
before_validation do
errors.add(:base, :oops) if with_validation_error
end
private
def raise_error_after_save
raise "save is called and expected to to raise" if raise_on_save
end
end
class Hemorrhoid
include SimplyBased::Model
enable_soft_delete
view :by_nickname_and_size, key: [:nickname, :size]
property :nickname
property :size
belongs_to :user
belongs_to :pain
belongs_to :spot
has_many :sub_hemorrhoids, dependent: :destroy
has_many :easy_sub_hemorrhoids, dependent: :destroy
has_many :rashs, dependent: :nullify
has_many :small_rashs, dependent: :nullify
before_destroy :before_destroy_callback
after_destroy :after_destroy_callback
def before_destroy_callback
end
def after_destroy_callback
end
end
class SubHemorrhoid
include SimplyBased::Model
enable_soft_delete
belongs_to :hemorrhoid
end
class EasySubHemorrhoid
include SimplyBased::Model
belongs_to :hemorrhoid
end
class Rash
include SimplyBased::Model
belongs_to :hemorrhoid
end
class SmallRash
include SimplyBased::Model
enable_soft_delete
belongs_to :hemorrhoid
end
class Pain
include SimplyBased::Model
has_many :hemorrhoids
has_many :users, through: :hemorrhoids
end
class Spot
include SimplyBased::Model
has_one :hemorrhoid
end
class Master
include SimplyBased::Model
has_many :servants, dependent: :ignore
end
class Servant
include SimplyBased::Model
belongs_to :master
end
class Issue
include SimplyBased::Model
belongs_to :problem
belongs_to :big_problem
property :name
end
class Problem
include SimplyBased::Model
has_many :issues
has_one :issue
end
class BigProblem < Problem
end
class Server
include SimplyBased::Model
property :hostname
has_and_belongs_to_many :networks, storing_keys: true
has_and_belongs_to_many :subnets, storing_keys: true
has_and_belongs_to_many :ips, storing_keys: false
end
class Network
include SimplyBased::Model
property :klass
has_and_belongs_to_many :servers, storing_keys: false
has_and_belongs_to_many :routers, storing_keys: false
end
class Subnet < Network
has_and_belongs_to_many :servers, storing_keys: false
end
class Ip
include SimplyBased::Model
has_and_belongs_to_many :servers, storing_keys: true
end
class Router
include SimplyBased::Model
enable_soft_delete
property :hostname
has_and_belongs_to_many :networks, storing_keys: true
end
class Book
include SimplyBased::Model
property :title
has_and_belongs_to_many :authors, storing_keys: true
end
class Author
include SimplyBased::Model
enable_soft_delete
property :name
has_and_belongs_to_many :books, storing_keys: false
end