Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 31 additions & 23 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
@@ -1,20 +1,24 @@
name: Gem Tests

on:
on:
pull_request:
push:
branches:
- master

jobs:
run:
name: Run Tests for Ruby ${{ matrix.ruby }}

test:
runs-on: ubuntu-latest
name: Ruby ${{ matrix.ruby }}
strategy:
fail-fast: false
matrix:
# Testing against all major supported Ruby versions
ruby: ['4.0', '3.5', '3.4', '3.3', '3.2', '3.1', '3.0', '2.7']

services:
postgres:
image: postgres
image: postgres:16
env:
POSTGRES_PASSWORD: postgres
POSTGRES_DB: pg_ltree_test
Expand All @@ -26,20 +30,6 @@ jobs:
--health-timeout 5s
--health-retries 5

strategy:
fail-fast: false
matrix:
ruby:
- 'head'
- '3.4'
- '3.3'
- '3.2'
- '3.1'
- '3.0'
- '2.7'

continue-on-error: ${{ matrix.ruby == 'head' }}

steps:
- uses: actions/checkout@v4

Expand All @@ -49,11 +39,29 @@ jobs:
ruby-version: ${{ matrix.ruby }}
bundler-cache: true

- name: Setup DB
- name: Setup DB config
run: cp spec/database.yml.sample spec/database.yml
- name: Install dependencies

- name: Install Appraisal dependencies
run: bundle exec appraisal install

- name: Run tests
- name: Run Tests (Appraisal)
run: bundle exec appraisal rake spec
env:
PGHOST: localhost
PGUSER: postgres
PGPASSWORD: postgres

# Dedicated job for linting to fail fast
lint:
runs-on: ubuntu-latest
name: Linting
steps:
- uses: actions/checkout@v4
- name: Set up Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: '3.4'
bundler-cache: true
- name: Run Lint
run: bundle exec rake lint
3 changes: 2 additions & 1 deletion Appraisals
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ def add_appraise_for(activerecord_version:, pg_version:)
end
end

SUPPORTED_PG_VERSIONS = ["~> 1.0", "~> 1.1", "~> 1.2", "~> 1.3", "~> 1.4", "~> 1.5"]
SUPPORTED_PG_VERSIONS = ["~> 1.0", "~> 1.1", "~> 1.2", "~> 1.3", "~> 1.4", "~> 1.5", "~> 1.6"]

if Gem::Version.new(RUBY_VERSION) <= Gem::Version.new("3.0")
SUPPORTED_PG_VERSIONS.map do |pg_version|
Expand Down Expand Up @@ -46,5 +46,6 @@ end
if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new("3.2")
SUPPORTED_PG_VERSIONS.map do |pg_version|
add_appraise_for(activerecord_version: "~> 8.0", pg_version: pg_version)
add_appraise_for(activerecord_version: "~> 8.1", pg_version: pg_version)
end
end
11 changes: 10 additions & 1 deletion Rakefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,15 @@ require "standard/rake"
require "rspec/core/rake_task"
require "appraisal"

desc "Run all tests"
RSpec::Core::RakeTask.new(:spec)

task default: :spec
desc "Run linting"
task lint: :standard

desc "Run all tests across all appraisals"
task :test_all do
sh "bundle exec appraisal rake spec"
end

task default: [:lint, :spec]
8 changes: 8 additions & 0 deletions gemfiles/activerecord_60_pg_16.gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# This file was generated by Appraisal

source "https://rubygems.org"

gem "activerecord", "~> 6.0", require: "active_record"
gem "pg", "~> 1.6"

gemspec path: "../"
8 changes: 8 additions & 0 deletions gemfiles/activerecord_61_pg_16.gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# This file was generated by Appraisal

source "https://rubygems.org"

gem "activerecord", "~> 6.1", require: "active_record"
gem "pg", "~> 1.6"

gemspec path: "../"
8 changes: 8 additions & 0 deletions gemfiles/activerecord_70_pg_16.gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# This file was generated by Appraisal

source "https://rubygems.org"

gem "activerecord", "~> 7.0", require: "active_record"
gem "pg", "~> 1.6"

gemspec path: "../"
8 changes: 8 additions & 0 deletions gemfiles/activerecord_71_pg_16.gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# This file was generated by Appraisal

source "https://rubygems.org"

gem "activerecord", "~> 7.1", require: "active_record"
gem "pg", "~> 1.6"

gemspec path: "../"
8 changes: 8 additions & 0 deletions gemfiles/activerecord_72_pg_16.gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# This file was generated by Appraisal

source "https://rubygems.org"

gem "activerecord", "~> 7.2", require: "active_record"
gem "pg", "~> 1.6"

gemspec path: "../"
8 changes: 8 additions & 0 deletions gemfiles/activerecord_80_pg_16.gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# This file was generated by Appraisal

source "https://rubygems.org"

gem "activerecord", "~> 8.0", require: "active_record"
gem "pg", "~> 1.6"

gemspec path: "../"
8 changes: 8 additions & 0 deletions gemfiles/activerecord_81_pg_10.gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# This file was generated by Appraisal

source "https://rubygems.org"

gem "activerecord", "~> 8.1", require: "active_record"
gem "pg", "~> 1.0"

gemspec path: "../"
8 changes: 8 additions & 0 deletions gemfiles/activerecord_81_pg_11.gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# This file was generated by Appraisal

source "https://rubygems.org"

gem "activerecord", "~> 8.1", require: "active_record"
gem "pg", "~> 1.1"

gemspec path: "../"
8 changes: 8 additions & 0 deletions gemfiles/activerecord_81_pg_12.gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# This file was generated by Appraisal

source "https://rubygems.org"

gem "activerecord", "~> 8.1", require: "active_record"
gem "pg", "~> 1.2"

gemspec path: "../"
8 changes: 8 additions & 0 deletions gemfiles/activerecord_81_pg_13.gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# This file was generated by Appraisal

source "https://rubygems.org"

gem "activerecord", "~> 8.1", require: "active_record"
gem "pg", "~> 1.3"

gemspec path: "../"
8 changes: 8 additions & 0 deletions gemfiles/activerecord_81_pg_14.gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# This file was generated by Appraisal

source "https://rubygems.org"

gem "activerecord", "~> 8.1", require: "active_record"
gem "pg", "~> 1.4"

gemspec path: "../"
8 changes: 8 additions & 0 deletions gemfiles/activerecord_81_pg_15.gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# This file was generated by Appraisal

source "https://rubygems.org"

gem "activerecord", "~> 8.1", require: "active_record"
gem "pg", "~> 1.5"

gemspec path: "../"
8 changes: 8 additions & 0 deletions gemfiles/activerecord_81_pg_16.gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# This file was generated by Appraisal

source "https://rubygems.org"

gem "activerecord", "~> 8.1", require: "active_record"
gem "pg", "~> 1.6"

gemspec path: "../"
38 changes: 2 additions & 36 deletions lib/pg_ltree/base.rb
Original file line number Diff line number Diff line change
@@ -1,44 +1,10 @@
require_relative "model"
require_relative "callbacks"
require_relative "configuration"

module PgLtree
module Base
extend ActiveSupport::Concern

class_methods do
attr_reader :ltree_options

# Initialize ltree module for the model
#
# @param column [String] lTree column name
# @param cascade_update [Boolean] Update all child nodes when the self path is changed
# @param cascade_destroy [Boolean] Destroy all child nodes on self-destroying
def ltree(column = :path, cascade_update: true, cascade_destroy: true, cascade: nil)
if cascade
ActiveSupport::Deprecation.warn("'cascade' param is deprecated. Use 'cascade_update' and 'cascade_destroy' instead.")
end

@ltree_options = {
column: column,
cascade_update: cascade.nil? ? cascade_update : cascade,
cascade_destroy: cascade.nil? ? cascade_destroy : cascade
}

send(:include, PgLtree::Model)
send(:include, PgLtree::Callbacks)
end

def ltree_options
@ltree_options || superclass.ltree_options
end

def ltree_option_for(key)
ltree_options[key]
end
end

included do
delegate :ltree_option_for, to: :class
end
include Configuration
end
end
17 changes: 0 additions & 17 deletions lib/pg_ltree/callbacks.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,23 +5,6 @@ module Callbacks
included do
after_commit :cascade_update, on: :update, if: -> { ltree_option_for :cascade_update }
after_commit :cascade_destroy, on: :destroy, if: -> { ltree_option_for :cascade_destroy }

# Update child nodes path
#
# @return [ActiveRecord::Relation]
def cascade_update
ltree_scope
.where(["#{self.class.table_name}.#{ltree_path_column} <@ ?", ltree_path_before_last_save])
.where(["#{self.class.table_name}.#{ltree_path_column} != ?", ltree_path])
.update_all ["#{ltree_path_column} = ? || subpath(#{ltree_path_column}, nlevel(?))", ltree_path, ltree_path_before_last_save]
end

# Destroy child nodes
#
# @return [ActiveRecord::Relation]
def cascade_destroy
ltree_scope.where("#{self.class.table_name}.#{ltree_path_column} <@ ?", ltree_path_in_database).destroy_all
end
end
end
end
43 changes: 43 additions & 0 deletions lib/pg_ltree/configuration.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
module PgLtree
module Configuration
extend ActiveSupport::Concern

class_methods do
attr_reader :ltree_options

# Initialize ltree module for the model
#
# @param column [String] lTree column name
# @param cascade_update [Boolean] Update all child nodes when the self path is changed
# @param cascade_destroy [Boolean] Destroy all child nodes on self-destroying
def ltree(column = :path, cascade_update: true, cascade_destroy: true, cascade: nil)
if cascade
ActiveSupport::Deprecation.warn("'cascade' param is deprecated. Use 'cascade_update' and 'cascade_destroy' instead.")
end

@ltree_options = {
column: column,
cascade_update: cascade.nil? ? cascade_update : cascade,
cascade_destroy: cascade.nil? ? cascade_destroy : cascade
}

send(:include, PgLtree::Model)
send(:include, PgLtree::Callbacks)
end

def ltree_options
@ltree_options || superclass.ltree_options
rescue NoMethodError
nil
end

def ltree_option_for(key)
ltree_options[key] if ltree_options
end
end

included do
delegate :ltree_option_for, to: :class
end
end
end
Loading
Loading