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>
355 lines
5.9 KiB
Ruby
355 lines
5.9 KiB
Ruby
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
|