preferred 0.1.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 +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +101 -0
- data/Rakefile +27 -0
- data/lib/preferred.rb +7 -0
- data/lib/preferred/preferable.rb +84 -0
- data/lib/preferred/preferable_class_methods.rb +69 -0
- data/lib/preferred/railtie.rb +4 -0
- data/lib/preferred/version.rb +3 -0
- data/lib/tasks/preferred_tasks.rake +4 -0
- metadata +96 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 845a796bc25a6fbbfdca3d033a224e6d5dc0f9d4
|
4
|
+
data.tar.gz: 417e5f78aeab9ae1e551207bf7c1d7cfc46cc07e
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: cfce22e8f4fe07323d9f6d67af82dfea84591e19c7e8291cc247899c330d553352dc54f4ec3cb921529c0b71712cf96d0531d08b1e719b95bf60f829b27f3408
|
7
|
+
data.tar.gz: 4d43fdb6179fac9ba952c4d830edb042d8888f9c50c626a0bfed68caac9c2be628c6bcdd2149bbfab067240cd7cc6c18126b840026b157ff59a75ccb892b3287
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright 2018
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,101 @@
|
|
1
|
+
# preferred
|
2
|
+
|
3
|
+
preferred provides a simple mechanism defining and storing preferences on a model.
|
4
|
+
This becomes powerful when used in conjunction with Single Table Inheritance
|
5
|
+
in Rails. Concepts for this gem were initially taken from the Spree open source
|
6
|
+
project and ported to use PostgreSQL JSONB columns instead of separate preferences
|
7
|
+
table.
|
8
|
+
|
9
|
+
# Usage
|
10
|
+
|
11
|
+
To install preferred add the following to your Gemfile
|
12
|
+
|
13
|
+
```ruby
|
14
|
+
gem 'preferred', git: 'https://github.com/nwwatson/preferred.git'
|
15
|
+
```
|
16
|
+
|
17
|
+
Once in your Gemfile
|
18
|
+
|
19
|
+
```shell
|
20
|
+
bundle install
|
21
|
+
```
|
22
|
+
|
23
|
+
# Simple Example
|
24
|
+
|
25
|
+
This simple example shows how to use preferred in a Rails model. Default values are optional. Preferred will provides types for string, decimal, integer, boolean, and date. Preferences are prefixed with "preferred_".
|
26
|
+
|
27
|
+
Create a model and ensure that it has a JSONB column called preference_hash
|
28
|
+
|
29
|
+
```shell
|
30
|
+
bin/rails g model example_model preference_hash:jsonb
|
31
|
+
```
|
32
|
+
|
33
|
+
Define preferences in the model and use
|
34
|
+
|
35
|
+
```ruby
|
36
|
+
class ExampleModel < ApplicationRecord
|
37
|
+
include Preferred::Preferable
|
38
|
+
|
39
|
+
preference :nickname, :string
|
40
|
+
preference :min_value, :decimal, default: 32.0
|
41
|
+
preference :year, :integer, default: 2018
|
42
|
+
preference :has_example, :boolean, default: true
|
43
|
+
preference :birthday, :date, default: Date.today
|
44
|
+
end
|
45
|
+
|
46
|
+
example_model = ExampleModel.new
|
47
|
+
example_model.has_preference?(:min_value) # returns true
|
48
|
+
example_model.preferred_min_value # returns 32.0
|
49
|
+
example_model.preferred_min_value = 0 # sets min_value to 0
|
50
|
+
example_model.preference_default(:min_value) # returns 32.0
|
51
|
+
example_model.preference_type(:min_value) # returns :decimal
|
52
|
+
```
|
53
|
+
|
54
|
+
# Complex example using Single Table Inheritance
|
55
|
+
|
56
|
+
Create base model
|
57
|
+
|
58
|
+
```
|
59
|
+
bin/rails g model strategy description:string type:string preference_hash:jsonb
|
60
|
+
```
|
61
|
+
|
62
|
+
## Include Preferable in Strategy model
|
63
|
+
|
64
|
+
```ruby
|
65
|
+
class Strategy < ApplicationRecord
|
66
|
+
include Preferred::Preferable
|
67
|
+
|
68
|
+
validates_presence_of :description
|
69
|
+
|
70
|
+
end
|
71
|
+
```
|
72
|
+
|
73
|
+
Define a models that extends Strategy
|
74
|
+
|
75
|
+
## WithinRange Strategy
|
76
|
+
|
77
|
+
```ruby
|
78
|
+
class WithinRange < Strategy
|
79
|
+
# The minimum temperature value for the range
|
80
|
+
preference :min, :decimal, default: 28.0
|
81
|
+
# The maximum temperature value for the range
|
82
|
+
preference :max, :decimal, default: 42.0
|
83
|
+
|
84
|
+
def good?(value)
|
85
|
+
(value => preferred_min) and (value <= preferred_max)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
```
|
89
|
+
|
90
|
+
## BelowMaximum Strategy
|
91
|
+
|
92
|
+
```ruby
|
93
|
+
class BelowMaximum < Strategy
|
94
|
+
# The maximum temperature allowed
|
95
|
+
preference :max, :decimal, default: 160.0
|
96
|
+
|
97
|
+
def good?(value)
|
98
|
+
value < preferred_max
|
99
|
+
end
|
100
|
+
end
|
101
|
+
```
|
data/Rakefile
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
begin
|
2
|
+
require 'bundler/setup'
|
3
|
+
rescue LoadError
|
4
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
5
|
+
end
|
6
|
+
|
7
|
+
require 'rdoc/task'
|
8
|
+
|
9
|
+
RDoc::Task.new(:rdoc) do |rdoc|
|
10
|
+
rdoc.rdoc_dir = 'rdoc'
|
11
|
+
rdoc.title = 'Preferred'
|
12
|
+
rdoc.options << '--line-numbers'
|
13
|
+
rdoc.rdoc_files.include('README.md')
|
14
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
15
|
+
end
|
16
|
+
|
17
|
+
require 'bundler/gem_tasks'
|
18
|
+
|
19
|
+
require 'rake/testtask'
|
20
|
+
|
21
|
+
Rake::TestTask.new(:test) do |t|
|
22
|
+
t.libs << 'test'
|
23
|
+
t.pattern = 'test/**/*_test.rb'
|
24
|
+
t.verbose = false
|
25
|
+
end
|
26
|
+
|
27
|
+
task default: :test
|
data/lib/preferred.rb
ADDED
@@ -0,0 +1,84 @@
|
|
1
|
+
module Preferred::Preferable
|
2
|
+
extend ActiveSupport::Concern
|
3
|
+
|
4
|
+
included do
|
5
|
+
extend PreferableClassMethods
|
6
|
+
end
|
7
|
+
|
8
|
+
def get_preference(name)
|
9
|
+
has_preference! name
|
10
|
+
send self.class.preference_getter_method(name)
|
11
|
+
end
|
12
|
+
alias :preferred :get_preference
|
13
|
+
alias :prefers? :get_preference
|
14
|
+
|
15
|
+
def set_preference(name, value)
|
16
|
+
has_preference! name
|
17
|
+
send self.class.preference_setter_method(name), value
|
18
|
+
end
|
19
|
+
|
20
|
+
def preference_type(name)
|
21
|
+
has_preference! name
|
22
|
+
send self.class.preference_type_getter_method(name)
|
23
|
+
end
|
24
|
+
|
25
|
+
def preference_default(name)
|
26
|
+
has_preference! name
|
27
|
+
send self.class.preference_default_getter_method(name)
|
28
|
+
end
|
29
|
+
|
30
|
+
def preference_description(name)
|
31
|
+
has_preference! name
|
32
|
+
send self.class.preference_description_getter_method(name)
|
33
|
+
end
|
34
|
+
|
35
|
+
def has_preference!(name)
|
36
|
+
raise NoMethodError.new "#{name} preference not defined" unless has_preference? name
|
37
|
+
end
|
38
|
+
|
39
|
+
def has_preference?(name)
|
40
|
+
respond_to? self.class.preference_getter_method(name)
|
41
|
+
end
|
42
|
+
|
43
|
+
def preferences
|
44
|
+
prefs = {}
|
45
|
+
methods.grep(/^prefers_.*\?$/).each do |pref_method|
|
46
|
+
prefs[pref_method.to_s.gsub(/prefers_|\?/, '').to_sym] = send(pref_method)
|
47
|
+
end
|
48
|
+
prefs
|
49
|
+
end
|
50
|
+
|
51
|
+
def clear_preferences
|
52
|
+
preference_hash.keys.each {|pref| preference_hash.delete pref} if preference_hash.is_a? Hash
|
53
|
+
end
|
54
|
+
|
55
|
+
private
|
56
|
+
|
57
|
+
def convert_preference_value(value, type)
|
58
|
+
case type
|
59
|
+
when :string, :text
|
60
|
+
value.to_s
|
61
|
+
when :password
|
62
|
+
value.to_s
|
63
|
+
when :decimal
|
64
|
+
BigDecimal.new(value.to_s)
|
65
|
+
when :integer
|
66
|
+
value.to_i
|
67
|
+
when :boolean
|
68
|
+
if value.is_a?(FalseClass) ||
|
69
|
+
value.nil? ||
|
70
|
+
value == 0 ||
|
71
|
+
value =~ /^(f|false|0)$/i ||
|
72
|
+
(value.respond_to? :empty? and value.empty?)
|
73
|
+
false
|
74
|
+
else
|
75
|
+
true
|
76
|
+
end
|
77
|
+
when :date
|
78
|
+
value.is_a?(Date) ? value : Date.parse(value)
|
79
|
+
else
|
80
|
+
value
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
module Preferred::Preferable
|
2
|
+
|
3
|
+
def preference(name, type, *args)
|
4
|
+
options = args.extract_options!
|
5
|
+
options.assert_valid_keys(:default, :description)
|
6
|
+
default = options[:default]
|
7
|
+
description = options[:description] || name
|
8
|
+
|
9
|
+
# cache_key will be nil for new objects, then if we check if there
|
10
|
+
# is a pending preference before going to default
|
11
|
+
define_method preference_getter_method(name) do
|
12
|
+
if self.preference_hash && preference_hash.key?(name.to_s)
|
13
|
+
convert_preference_value(preference_hash[name.to_s]["value"], preference_hash[name.to_s]["type"])
|
14
|
+
else
|
15
|
+
send self.class.preference_default_getter_method(name)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
define_method preference_setter_method(name) do |value|
|
20
|
+
value = convert_preference_value(value, type)
|
21
|
+
self.preference_hash = {} if preference_hash.nil?
|
22
|
+
self.preference_hash[name.to_s] = {
|
23
|
+
value: value,
|
24
|
+
type: type
|
25
|
+
}
|
26
|
+
end
|
27
|
+
|
28
|
+
define_method preference_default_getter_method(name) do
|
29
|
+
default
|
30
|
+
end
|
31
|
+
|
32
|
+
define_method preference_type_getter_method(name) do
|
33
|
+
type
|
34
|
+
end
|
35
|
+
|
36
|
+
define_method preference_description_getter_method(name) do
|
37
|
+
description
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def remove_preference(name)
|
42
|
+
remove_method preference_getter_method(name) if method_defined? preference_getter_method(name)
|
43
|
+
remove_method preference_setter_method(name) if method_defined? preference_setter_method(name)
|
44
|
+
remove_method preference_default_getter_method(name) if method_defined? preference_default_getter_method(name)
|
45
|
+
remove_method preference_type_getter_method(name) if method_defined? preference_type_getter_method(name)
|
46
|
+
remove_method preference_description_getter_method(name) if method_defined? preference_description_getter_method(name)
|
47
|
+
end
|
48
|
+
|
49
|
+
def preference_getter_method(name)
|
50
|
+
"preferred_#{name}".to_sym
|
51
|
+
end
|
52
|
+
|
53
|
+
def preference_setter_method(name)
|
54
|
+
"preferred_#{name}=".to_sym
|
55
|
+
end
|
56
|
+
|
57
|
+
def preference_default_getter_method(name)
|
58
|
+
"preferred_#{name}_default".to_sym
|
59
|
+
end
|
60
|
+
|
61
|
+
def preference_type_getter_method(name)
|
62
|
+
"preferred_#{name}_type".to_sym
|
63
|
+
end
|
64
|
+
|
65
|
+
def preference_description_getter_method(name)
|
66
|
+
"preferred_#{name}_description".to_sym
|
67
|
+
end
|
68
|
+
|
69
|
+
end
|
metadata
ADDED
@@ -0,0 +1,96 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: preferred
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Nicholas W. Watson
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2018-03-14 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rails
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '4.0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '4.0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: pg
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 0.18.1
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 0.18.1
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: sqlite3
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
description: Preferred allows you to define preferences on a model and stores them
|
56
|
+
in a jsonb column in PostgreSQL
|
57
|
+
email:
|
58
|
+
- nicholas.w.watson@me.com
|
59
|
+
executables: []
|
60
|
+
extensions: []
|
61
|
+
extra_rdoc_files: []
|
62
|
+
files:
|
63
|
+
- MIT-LICENSE
|
64
|
+
- README.md
|
65
|
+
- Rakefile
|
66
|
+
- lib/preferred.rb
|
67
|
+
- lib/preferred/preferable.rb
|
68
|
+
- lib/preferred/preferable_class_methods.rb
|
69
|
+
- lib/preferred/railtie.rb
|
70
|
+
- lib/preferred/version.rb
|
71
|
+
- lib/tasks/preferred_tasks.rake
|
72
|
+
homepage: https://github.com/nwwatson/preferred
|
73
|
+
licenses:
|
74
|
+
- MIT
|
75
|
+
metadata: {}
|
76
|
+
post_install_message:
|
77
|
+
rdoc_options: []
|
78
|
+
require_paths:
|
79
|
+
- lib
|
80
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
81
|
+
requirements:
|
82
|
+
- - ">="
|
83
|
+
- !ruby/object:Gem::Version
|
84
|
+
version: '0'
|
85
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
requirements: []
|
91
|
+
rubyforge_project:
|
92
|
+
rubygems_version: 2.5.2
|
93
|
+
signing_key:
|
94
|
+
specification_version: 4
|
95
|
+
summary: Preferences on your Rails models stored in a JSONB column in PostgreSQL
|
96
|
+
test_files: []
|