preferred 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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,7 @@
1
+ require "preferred/railtie"
2
+ require "preferred/preferable_class_methods"
3
+ require "preferred/preferable"
4
+
5
+ module Preferred
6
+ # Your code goes here...
7
+ end
@@ -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
@@ -0,0 +1,4 @@
1
+ module Preferred
2
+ class Railtie < ::Rails::Railtie
3
+ end
4
+ end
@@ -0,0 +1,3 @@
1
+ module Preferred
2
+ VERSION = '0.1.0'
3
+ end
@@ -0,0 +1,4 @@
1
+ # desc "Explaining what the task does"
2
+ # task :preferred do
3
+ # # Task goes here
4
+ # 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: []