quantum_fields 0.1.1 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/quantum_fields.rb +13 -0
- data/lib/quantum_fields/active_record_patch.rb +5 -1
- data/lib/quantum_fields/exceptions.rb +9 -0
- data/lib/quantum_fields/no_sqlize.rb +25 -14
- data/lib/quantum_fields/support.rb +1 -1
- data/lib/quantum_fields/support/{mysql.rb → mysql2.rb} +1 -1
- data/lib/quantum_fields/validation_injector.rb +4 -0
- data/lib/quantum_fields/version.rb +1 -1
- metadata +32 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 225219c6eb2031eac5edd7900a35e3f7c5ce6025175901a7fae160bbf4dc1661
|
4
|
+
data.tar.gz: b02f1f72ee6fefa63d2a0264fd1d04cc27b07c9fffe7c6561799f0667cd06aea
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 34cafe75d21a630b2c3e647c92b4e623eaa8ec6ea3b363325a1fdcfc5f7ed9afa54f2451dc5bdffba6bf4de64c0ef3f2cf81cbb5283051d5454087ab339c6b98
|
7
|
+
data.tar.gz: dccc02766d88453f2006a85426a364a1165db38352e0af5e84be6b98b3e508ad1b4306b4082de485dc514134d9ff5a4b3afbc2b9d7256988fc1cf35139f14aee
|
data/lib/quantum_fields.rb
CHANGED
@@ -16,6 +16,19 @@ module QuantumFields
|
|
16
16
|
# This module contains the methods called within the Model to initialize
|
17
17
|
# and to manage how the other methods should behave on the given context.
|
18
18
|
module ClassMethods
|
19
|
+
# Method called in the model context to initialize behavior and pass
|
20
|
+
# configuration options into quantum_fields. You can use a custom column
|
21
|
+
# for your fields and a custom column for your injected validation rules.
|
22
|
+
# Initializing the gem behavior on default 'quantum_fields' and
|
23
|
+
# 'quantum_rules' columns:
|
24
|
+
# => no_sqlize
|
25
|
+
# Initializing the gem behavior on default 'quantum_rules' column and a
|
26
|
+
# custom fields_column 'my_json_field'
|
27
|
+
# => no_sqlize fields_column: :my_json_field
|
28
|
+
# Initializing the gem behavior on default 'quantum_fields' column and a
|
29
|
+
# custom rules_column 'my_json_field', affecting from where to pull
|
30
|
+
# injected validations:
|
31
|
+
# => no_sqlize rules_column: :my_json_field
|
19
32
|
def no_sqlize(args = {})
|
20
33
|
class_eval <<-RUBY, __FILE__, __LINE__+1
|
21
34
|
def self.fields_column
|
@@ -1,6 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
ActiveRecord::PredicateBuilder.class_eval do
|
4
|
+
# Builds an binded Arel operation, injecting json operator if necessary
|
4
5
|
def build(attribute, value)
|
5
6
|
if table.type(attribute.name).force_equality?(value)
|
6
7
|
bind = build_bind_attribute(attribute.name, value)
|
@@ -16,7 +17,10 @@ ActiveRecord::PredicateBuilder.class_eval do
|
|
16
17
|
end
|
17
18
|
end
|
18
19
|
ActiveRecord::Relation.class_eval do
|
19
|
-
|
20
|
+
# Returns an Arel::Node that is used to query a field.
|
21
|
+
# In case that attribute is a column or if current model
|
22
|
+
# hasn't initialized 'no_sqlize' keeps Rails' behavior.
|
23
|
+
def arel_attribute(name)
|
20
24
|
if klass.column_names.include?(name.to_s) || !klass.respond_to?(:fields_column)
|
21
25
|
klass.arel_attribute(name, table)
|
22
26
|
else
|
@@ -1,5 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'quantum_fields/exceptions'
|
3
4
|
module QuantumFields
|
4
5
|
# Module to enable virtual methods in moduls, it creates necessary
|
5
6
|
# methods to simulate the behavior that any field can exist, getting
|
@@ -10,12 +11,10 @@ module QuantumFields
|
|
10
11
|
# into `.parameters` JSON as a key-value pair, or recovering it's value if
|
11
12
|
# exists.
|
12
13
|
def method_missing(meth, *args, &block)
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
"#{model.table_name} should have a `#{fields_column}` JSON column"
|
18
|
-
end
|
14
|
+
method_name = meth.to_s
|
15
|
+
super if method_name.ends_with?('!')
|
16
|
+
bad_config! unless can_no_sqlize?
|
17
|
+
no_sqlize!(method_name, *args, &block)
|
19
18
|
rescue StandardError
|
20
19
|
super
|
21
20
|
end
|
@@ -24,10 +23,10 @@ module QuantumFields
|
|
24
23
|
# the premisse that you can always assign a value to any field and recover
|
25
24
|
# only existing fields or the ones that are in the `.parameters` JSON.
|
26
25
|
def respond_to_missing?(method_name, include_private = false)
|
26
|
+
bad_config! unless can_no_sqlize?
|
27
27
|
meth = method_name.to_s
|
28
|
-
|
29
|
-
try(fields_column).try(:[], meth).present? ||
|
30
|
-
super
|
28
|
+
meth.ends_with?('=') || meth.ends_with?('?') ||
|
29
|
+
try(fields_column).try(:[], meth).present? || super
|
31
30
|
end
|
32
31
|
|
33
32
|
# Overriding a ActiveRecord method that is used in `.create` and `.update`
|
@@ -58,15 +57,21 @@ module QuantumFields
|
|
58
57
|
# The behavior that a noSQL method should have. It either assigns a value into
|
59
58
|
# an attribute or retrieves it's value, depending in the method called.
|
60
59
|
def no_sqlize!(meth, *args, &_block)
|
61
|
-
method_name = meth.to_s
|
62
60
|
initialize_fields
|
63
|
-
if
|
64
|
-
assing_to(
|
61
|
+
if meth.ends_with?('=')
|
62
|
+
assing_to(meth.chomp('='), args.first)
|
63
|
+
elsif meth.ends_with?('?')
|
64
|
+
read_nosqlized(meth.chomp('?')).present?
|
65
65
|
else
|
66
|
-
|
66
|
+
read_nosqlized(meth)
|
67
67
|
end
|
68
68
|
end
|
69
69
|
|
70
|
+
# Read the value of a `meth` key in :fields_column
|
71
|
+
def read_nosqlized(meth)
|
72
|
+
try(fields_column).try(:[], meth)
|
73
|
+
end
|
74
|
+
|
70
75
|
# Assings a value to a key in :fields_column which allows saving any virtual
|
71
76
|
# attribute
|
72
77
|
def assing_to(param, value)
|
@@ -76,12 +81,18 @@ module QuantumFields
|
|
76
81
|
# Checks if requirements are met for the feature
|
77
82
|
def can_no_sqlize?
|
78
83
|
model.column_names.include?(fields_column.to_s) &&
|
79
|
-
%i[json jsonb].include?(no_sqlize_column.type)
|
84
|
+
%i[hstore json jsonb].include?(no_sqlize_column.type)
|
80
85
|
end
|
81
86
|
|
82
87
|
# Retrieve which column is being used to sqlize
|
83
88
|
def no_sqlize_column
|
84
89
|
model.columns.find { |col| col.name == fields_column.to_s }
|
85
90
|
end
|
91
|
+
|
92
|
+
# Raises an exception indicating bad configuration of the gem
|
93
|
+
def bad_config!
|
94
|
+
raise QuantumFields::NoSqlizedFieldsColumnMissing,
|
95
|
+
"#{model.table_name} should have a `#{fields_column}` JSON column"
|
96
|
+
end
|
86
97
|
end
|
87
98
|
end
|
@@ -3,7 +3,7 @@
|
|
3
3
|
module QuantumFields
|
4
4
|
module Support
|
5
5
|
# Abstracts MySQL support for quantum_fields operations
|
6
|
-
module
|
6
|
+
module Mysql2
|
7
7
|
class << self
|
8
8
|
# Returns an Arel node in the context of given field and JSON key,
|
9
9
|
# which in this context constructs as "json_extract("my_models"."my_json_field", '$.key')"
|
@@ -7,6 +7,7 @@ module QuantumFields
|
|
7
7
|
extend ActiveSupport::Concern
|
8
8
|
included do
|
9
9
|
before_validation :map_injected_validations
|
10
|
+
# Maps your rules_column for defined validations
|
10
11
|
def map_injected_validations
|
11
12
|
send(self.class.rules_column).try(:deep_symbolize_keys)&.each do |field, rules|
|
12
13
|
validations = rules[:validates]
|
@@ -14,6 +15,9 @@ module QuantumFields
|
|
14
15
|
end
|
15
16
|
end
|
16
17
|
|
18
|
+
private
|
19
|
+
|
20
|
+
# Injects validations on a given field
|
17
21
|
def inject_validations(field, validations)
|
18
22
|
validations.each do |method, value|
|
19
23
|
singleton_class.validates field, method => value
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: quantum_fields
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Fernando Bellincanta
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-02-
|
11
|
+
date: 2019-02-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -52,6 +52,34 @@ dependencies:
|
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: 1.3.6
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: pg
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: mysql2
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
55
83
|
description: QuantumFields is a gem to extend your Rails model's making them able
|
56
84
|
to use virtual fields from a JSON column or a Text column serialized as a Hash.
|
57
85
|
This means that you can use fields that were not explicitly declared in your schema
|
@@ -67,10 +95,11 @@ files:
|
|
67
95
|
- Rakefile
|
68
96
|
- lib/quantum_fields.rb
|
69
97
|
- lib/quantum_fields/active_record_patch.rb
|
98
|
+
- lib/quantum_fields/exceptions.rb
|
70
99
|
- lib/quantum_fields/no_sqlize.rb
|
71
100
|
- lib/quantum_fields/railtie.rb
|
72
101
|
- lib/quantum_fields/support.rb
|
73
|
-
- lib/quantum_fields/support/
|
102
|
+
- lib/quantum_fields/support/mysql2.rb
|
74
103
|
- lib/quantum_fields/support/postgresql.rb
|
75
104
|
- lib/quantum_fields/support/sqlite3.rb
|
76
105
|
- lib/quantum_fields/validation_injector.rb
|