From 7357ebae6bd28752f31e02c6d04c47f6f2bd5c0c Mon Sep 17 00:00:00 2001 From: Piero Dotti Date: Thu, 13 Jul 2023 17:04:35 +0200 Subject: [PATCH] fix(inheritance): allow models inheritance without bugs --- CHANGELOG.md | 4 ++++ acts_as_nosql.gemspec | 2 +- lib/acts_as_nosql.rb | 10 +++++++++- lib/acts_as_nosql/attribute.rb | 6 +++++- lib/acts_as_nosql/attributes.rb | 5 +++++ lib/acts_as_nosql/querying.rb | 1 + lib/acts_as_nosql/version.rb | 4 +++- spec/acts_as_nosql/inheritance_spec.rb | 22 ++++++++++++++++++++++ spec/support/schema.rb | 9 +++++++++ 9 files changed, 59 insertions(+), 4 deletions(-) create mode 100644 spec/acts_as_nosql/inheritance_spec.rb diff --git a/CHANGELOG.md b/CHANGELOG.md index 9119d0d..4232890 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,10 @@ # Changelog All notable changes to this project made by Monade Team are documented in this file. For info refer to team@monade.io +## [0.1.2] +### Fixed +- Bug with inheritance: attributes declared in parent classes where not propagated to child classes + ## [0.1.1] ### Fixed - Name conflicts between columns and nosql attributes where not detected diff --git a/acts_as_nosql.gemspec b/acts_as_nosql.gemspec index 91c1f35..2734804 100644 --- a/acts_as_nosql.gemspec +++ b/acts_as_nosql.gemspec @@ -17,8 +17,8 @@ Gem::Specification.new do |s| s.homepage = 'https://rubygems.org/gems/acts_as_nosql' s.license = 'MIT' s.add_dependency 'actionpack', ['>= 5', '< 8'] - s.add_dependency 'activesupport', ['>= 5', '< 8'] s.add_dependency 'activerecord', ['>= 5', '< 8'] + s.add_dependency 'activesupport', ['>= 5', '< 8'] s.add_development_dependency 'rspec', '~> 3' s.add_development_dependency 'rubocop' end diff --git a/lib/acts_as_nosql.rb b/lib/acts_as_nosql.rb index bedd49f..7226a93 100644 --- a/lib/acts_as_nosql.rb +++ b/lib/acts_as_nosql.rb @@ -1,12 +1,20 @@ +# frozen_string_literal: true + require 'active_record' +# ActsAsNosql +# +# This gem allows to handle JSON and JSONB fields as if they are proper +# database columns, handling default values, type casting and simplifying +# validation. +# This module is the main entry point for the gem. module ActsAsNosql extend ActiveSupport::Concern extend ActiveSupport::Autoload class_methods do attr_accessor :_acts_as_nosql_options - # cattr_accessor :_acts_as_nosql_options + def acts_as_nosql(field_name: nil) @_acts_as_nosql_options = { field_name: field_name } diff --git a/lib/acts_as_nosql/attribute.rb b/lib/acts_as_nosql/attribute.rb index f437807..7390b11 100644 --- a/lib/acts_as_nosql/attribute.rb +++ b/lib/acts_as_nosql/attribute.rb @@ -3,11 +3,15 @@ module ActsAsNosql class Attribute attr_reader :name, :type, :default, :path, :type_caster + # @param [String, Symbol] name + # @param [String, Symbol, nil] type + # @param [Object, nil] default + # @param [Array, nil] path def initialize(name, type: nil, default: nil, path: nil) @name = name.to_s @type = type @default = default - @path = path&.map { |p| p.to_s } + @path = path&.map(&:to_s) @type_caster = type ? "ActiveRecord::Type::#{type}".safe_constantize : nil end diff --git a/lib/acts_as_nosql/attributes.rb b/lib/acts_as_nosql/attributes.rb index 1f2e10a..440f7ca 100644 --- a/lib/acts_as_nosql/attributes.rb +++ b/lib/acts_as_nosql/attributes.rb @@ -29,6 +29,11 @@ def nosql_attr(*names, type: nil, default: nil, path: nil) end end + def inherited(subclass) + subclass._acts_as_nosql_options = self._acts_as_nosql_options.deep_dup + super + end + def nosql_attributes self._acts_as_nosql_options[:attributes] ||= {} end diff --git a/lib/acts_as_nosql/querying.rb b/lib/acts_as_nosql/querying.rb index bc1e51c..b26c881 100644 --- a/lib/acts_as_nosql/querying.rb +++ b/lib/acts_as_nosql/querying.rb @@ -1,3 +1,4 @@ +# frozen_string_literal: true module ActsAsNosql module Querying diff --git a/lib/acts_as_nosql/version.rb b/lib/acts_as_nosql/version.rb index 7d57e31..6b1d54b 100644 --- a/lib/acts_as_nosql/version.rb +++ b/lib/acts_as_nosql/version.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module ActsAsNosql - VERSION = '0.1.1'.freeze + VERSION = '0.1.2'.freeze end diff --git a/spec/acts_as_nosql/inheritance_spec.rb b/spec/acts_as_nosql/inheritance_spec.rb new file mode 100644 index 0000000..93a7d10 --- /dev/null +++ b/spec/acts_as_nosql/inheritance_spec.rb @@ -0,0 +1,22 @@ +require 'spec_helper' + +describe 'Inheritance' do + subject { InheritedSetting.new } + it 'inherits all methods from Settings' do + expect(subject).to respond_to(:user_auth_token) + expect(subject).to respond_to(:user_auth_token=) + + subject.user_auth_token = '3' + expect(subject.user_auth_token).to eq('3') + subject.save! + expect do + expect(InheritedSetting.where(user_auth_token: '3')).to eq([subject]) + end.to_not raise_error + end + + it 'can be estended without affecting the parent' do + InheritedSetting.nosql_attrs :hello, type: :String + expect(subject).to respond_to(:hello) + expect(Setting.new).not_to respond_to(:hello) + end +end diff --git a/spec/support/schema.rb b/spec/support/schema.rb index 554f4f0..decf8c7 100644 --- a/spec/support/schema.rb +++ b/spec/support/schema.rb @@ -44,6 +44,9 @@ class Setting < ActiveRecord::Base nosql_attrs :user_auth_providers, type: Array, default: [], path: [:user, :auth, :providers] end +class InheritedSetting < Setting +end + module Schema def self.create ActiveRecord::Migration.verbose = false @@ -60,6 +63,12 @@ def self.create t.json :config t.timestamps null: false end + + create_table :inherited_settings, force: true do |t| + t.string :title + t.json :config + t.timestamps null: false + end end end end