preferencias 0.0.1

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.
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ ZmQyMjVhN2RkOTExNzIyYmE2OGI4YmM4MWI2N2E4Yjg3Yzc1MmJkOQ==
5
+ data.tar.gz: !binary |-
6
+ MzcyMjBiNDdlYjFkZmNmODA0MThmODc3OWRkYzkzMDM4OTc0ODFhMg==
7
+ SHA512:
8
+ metadata.gz: !binary |-
9
+ Mzk4YTkyNTVkYzBkYzcwZTZhYTU5Y2M3ODI2MWQxMjJmNTc3NGFhZTAwZDJk
10
+ MWJmZjJkMDQ1MzY3ZWMyZTA0ZTBjZjljMTgxMTY3OGQ3ZjZhZDVmNWU0M2Jh
11
+ YTk5ODllNDY0MGI0ZjY2YWI5ZDUxMGMyYTdiZDkwOGEyZDRkZmY=
12
+ data.tar.gz: !binary |-
13
+ MTNjNzhkOTQ0YTA1YWRjMDMxZGExY2E3NTJjMTlmMTQ0MTY0NzQ5OWNmZjE5
14
+ MGVlOWNlYWJkZDBiYjJlNmU5ZWE4NjgzOTk0MTViOWE0ZDUyZGI0OWI2N2Jl
15
+ OWQ0NjNhYTc3OGJjYWUxNDQ4OWEzNzU4YjA1MmI2NTQzN2FhOTc=
@@ -0,0 +1,23 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ *.bundle
19
+ *.so
20
+ *.o
21
+ *.a
22
+ mkmf.log
23
+ .DS_Store
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --require spec_helper
@@ -0,0 +1,5 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.9.3
4
+ - 2.0.0
5
+ - 2.1.0
data/Gemfile ADDED
@@ -0,0 +1,7 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in preferencias.gemspec
4
+ gemspec
5
+
6
+ gem 'pry', group: :test
7
+ gem 'pry-nav', group: :test
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 David Silva
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,47 @@
1
+ # PreferĂȘncias
2
+
3
+ [![Build Status](https://travis-ci.org/Davidslv/preferences.svg?branch=master)](https://travis-ci.org/davidslv/preferences)
4
+
5
+ This gem is an extraction of the [Spree Ecommerce](https://github.com/spree/spree) Open Source Software.
6
+
7
+ I couldn't find anything as robust as their solution so I decided to extract it into a gem.
8
+
9
+ ## Installation
10
+
11
+ Add this line to your application's Gemfile:
12
+
13
+ gem 'preferencias'
14
+
15
+ And then execute:
16
+
17
+ $ bundle
18
+
19
+ Or install it yourself as:
20
+
21
+ $ gem install preferencias
22
+
23
+ Run migrations
24
+
25
+ $ rails generate preferencias:migration
26
+ $ bundle exec rake db:migrate db:test:prepare
27
+
28
+ ## Usage
29
+
30
+ ```ruby
31
+ class YourModel < ActiveRecord::Base
32
+ preference :color, :string, default: 'red'
33
+ preference :number_of_pokemons, :integer, default: 151
34
+ end
35
+
36
+ @model = YourModel.create(preferences: {number_of_pokemons: 649})
37
+ @model.preferred_number_of_pokemons # => 649
38
+ @model.preferred_color # => "red"
39
+ ```
40
+
41
+ ## Contributing
42
+
43
+ 1. Fork it ( https://github.com/davidslv/preferences/fork )
44
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
45
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
46
+ 4. Push to the branch (`git push origin my-new-feature`)
47
+ 5. Create a new Pull Request
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require 'rspec/core/rake_task'
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
@@ -0,0 +1,22 @@
1
+ require 'rails/generators'
2
+ require 'rails/generators/migration'
3
+
4
+ module Preferencias
5
+ class MigrationGenerator < ::Rails::Generators::Base
6
+ include ::Rails::Generators::Migration
7
+ source_root File.expand_path('../templates', __FILE__)
8
+
9
+ def self.next_migration_number( dirname )
10
+ next_migration_number = current_migration_number(dirname) + 1
11
+ if ActiveRecord::Base.timestamped_migrations
12
+ [Time.now.utc.strftime("%Y%m%d%H%M%S%6N"), "%.20d" % next_migration_number].max
13
+ else
14
+ "%.3d" % next_migration_number
15
+ end
16
+ end
17
+
18
+ def create_model_file
19
+ migration_template "create_preferences.rb", "db/migrate/create_preferences.rb"
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,10 @@
1
+ class CreatePreferences < ActiveRecord::Migration
2
+ def change
3
+ create_table "preferences", force: true do |t|
4
+ t.text "value"
5
+ t.string "key"
6
+ end
7
+
8
+ add_index "preferences", ["key"], name: "preferences_on_key", unique: true, using: :btree
9
+ end
10
+ end
@@ -0,0 +1,51 @@
1
+ module Preferencias
2
+ module PreferableClassMethods
3
+
4
+ def preference(name, type, *args)
5
+ options = args.extract_options!
6
+ options.assert_valid_keys(:default)
7
+ default = options[:default]
8
+ default = ->{ options[:default] } unless default.is_a?(Proc)
9
+
10
+ # cache_key will be nil for new objects, then if we check if there
11
+ # is a pending preference before going to default
12
+ define_method preference_getter_method(name) do
13
+ preferences.fetch(name) do
14
+ default.call
15
+ end
16
+ end
17
+
18
+ define_method preference_setter_method(name) do |value|
19
+ value = convert_preference_value(value, type)
20
+ preferences[name] = value
21
+
22
+ # If this is an activerecord object, we need to inform
23
+ # ActiveRecord::Dirty that this value has changed, since this is an
24
+ # in-place update to the preferences hash.
25
+ preferences_will_change! if respond_to?(:preferences_will_change!)
26
+ end
27
+
28
+ define_method preference_default_getter_method(name), &default
29
+
30
+ define_method preference_type_getter_method(name) do
31
+ type
32
+ end
33
+ end
34
+
35
+ def preference_getter_method(name)
36
+ "preferred_#{name}".to_sym
37
+ end
38
+
39
+ def preference_setter_method(name)
40
+ "preferred_#{name}=".to_sym
41
+ end
42
+
43
+ def preference_default_getter_method(name)
44
+ "preferred_#{name}_default".to_sym
45
+ end
46
+
47
+ def preference_type_getter_method(name)
48
+ "preferred_#{name}_type".to_sym
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,7 @@
1
+ require "preferencias/version"
2
+
3
+ module Preferencias
4
+ module Rails
5
+ require 'preferencias/engine'
6
+ end
7
+ end
@@ -0,0 +1,14 @@
1
+ require 'active_record'
2
+
3
+ module Preferencias
4
+ class Base < ActiveRecord::Base
5
+ include Preferencias::Preferable
6
+
7
+ serialize :preferences, Hash
8
+ after_initialize do
9
+ self.preferences = default_preferences.merge(preferences) if has_attribute?(:preferences)
10
+ end
11
+
12
+ self.abstract_class = true
13
+ end
14
+ end
@@ -0,0 +1,17 @@
1
+ require 'preferencias/preferences/preferable_class_methods'
2
+ require 'preferencias/preferences/preferable'
3
+ require 'preferencias/base'
4
+ require 'preferencias/preferences/configuration'
5
+ require 'preferencias/preferences/scoped_store'
6
+ require 'preferencias/preferences/store'
7
+ require 'preferencias/preference.rb'
8
+
9
+ require 'rails'
10
+
11
+ module Preferencias
12
+ class Engine < ::Rails::Engine
13
+ initializer "preferences" do
14
+ ::ActiveRecord::Base.send :include, Preferencias::Preferable
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,6 @@
1
+ module Preferencias
2
+ class Preference < Base
3
+ serialize :value
4
+ validates :key, presence: true, uniqueness: true
5
+ end
6
+ end
@@ -0,0 +1,71 @@
1
+ # This takes the preferrable methods and adds some
2
+ # syntatic sugar to access the preferences
3
+ #
4
+ # class App < Configuration
5
+ # preference :color, :string
6
+ # end
7
+ #
8
+ # a = App.new
9
+ #
10
+ # setters:
11
+ # a.color = :blue
12
+ # a[:color] = :blue
13
+ # a.set :color = :blue
14
+ # a.preferred_color = :blue
15
+ #
16
+ # getters:
17
+ # a.color
18
+ # a[:color]
19
+ # a.get :color
20
+ # a.preferred_color
21
+ #
22
+ #
23
+ module Preferencias
24
+ class Configuration
25
+ include Preferencias::Preferable
26
+
27
+ def configure
28
+ yield(self) if block_given?
29
+ end
30
+
31
+ def preferences
32
+ ScopedStore.new(self.class.name.underscore)
33
+ end
34
+
35
+ def reset
36
+ preferences.each do |name, value|
37
+ set_preference name, preference_default(name)
38
+ end
39
+ end
40
+
41
+ alias :[] :get_preference
42
+ alias :[]= :set_preference
43
+
44
+ alias :get :get_preference
45
+
46
+ def set(*args)
47
+ options = args.extract_options!
48
+ options.each do |name, value|
49
+ set_preference name, value
50
+ end
51
+
52
+ if args.size == 2
53
+ set_preference args[0], args[1]
54
+ end
55
+ end
56
+
57
+ def method_missing(method, *args)
58
+ name = method.to_s.gsub('=', '')
59
+ if has_preference? name
60
+ if method.to_s =~ /=$/
61
+ set_preference(name, args.first)
62
+ else
63
+ get_preference name
64
+ end
65
+ else
66
+ super
67
+ end
68
+ end
69
+
70
+ end
71
+ end
@@ -0,0 +1,116 @@
1
+ # Preferable allows defining preference accessor methods.
2
+ #
3
+ # A class including Preferable must implement #preferences which should return
4
+ # an object responding to .fetch(key), []=(key, val), and .delete(key).
5
+ #
6
+ # The generated writer method performs typecasting before assignment into the
7
+ # preferences object.
8
+ #
9
+ # Examples:
10
+ #
11
+ # # Base includes Preferable and defines preferences as a serialized
12
+ # # column.
13
+ # class Settings < Base
14
+ # preference :color, :string, default: 'red'
15
+ # preference :temperature, :integer, default: 21
16
+ # end
17
+ #
18
+ # s = Settings.new
19
+ # s.preferred_color # => 'red'
20
+ # s.preferred_temperature # => 21
21
+ #
22
+ # s.preferred_color = 'blue'
23
+ # s.preferred_color # => 'blue'
24
+ #
25
+ # # Typecasting is performed on assignment
26
+ # s.preferred_temperature = '24'
27
+ # s.preferred_color # => 24
28
+ #
29
+ # # Modifications have been made to the .preferences hash
30
+ # s.preferences #=> {color: 'blue', temperature: 24}
31
+ #
32
+ # # Save the changes. All handled by activerecord
33
+ # s.save!
34
+
35
+ require 'active_support'
36
+
37
+ module Preferencias::Preferable
38
+ extend ActiveSupport::Concern
39
+
40
+ included do
41
+ extend Preferencias::PreferableClassMethods
42
+ end
43
+
44
+ def get_preference(name)
45
+ has_preference! name
46
+ send self.class.preference_getter_method(name)
47
+ end
48
+
49
+ def set_preference(name, value)
50
+ has_preference! name
51
+ send self.class.preference_setter_method(name), value
52
+ end
53
+
54
+ def preference_type(name)
55
+ has_preference! name
56
+ send self.class.preference_type_getter_method(name)
57
+ end
58
+
59
+ def preference_default(name)
60
+ has_preference! name
61
+ send self.class.preference_default_getter_method(name)
62
+ end
63
+
64
+ def has_preference!(name)
65
+ raise NoMethodError.new "#{name} preference not defined" unless has_preference? name
66
+ end
67
+
68
+ def has_preference?(name)
69
+ respond_to? self.class.preference_getter_method(name)
70
+ end
71
+
72
+ def defined_preferences
73
+ methods.grep(/\Apreferred_.*=\Z/).map do |pref_method|
74
+ pref_method.to_s.gsub(/\Apreferred_|=\Z/, '').to_sym
75
+ end
76
+ end
77
+
78
+ def default_preferences
79
+ Hash[
80
+ defined_preferences.map do |preference|
81
+ [preference, preference_default(preference)]
82
+ end
83
+ ]
84
+ end
85
+
86
+ def clear_preferences
87
+ preferences.keys.each {|pref| preferences.delete pref}
88
+ end
89
+
90
+ private
91
+
92
+ def convert_preference_value(value, type)
93
+ case type
94
+ when :string, :text
95
+ value.to_s
96
+ when :password
97
+ value.to_s
98
+ when :decimal
99
+ BigDecimal.new(value.to_s)
100
+ when :integer
101
+ value.to_i
102
+ when :boolean
103
+ if value.is_a?(FalseClass) ||
104
+ value.nil? ||
105
+ value == 0 ||
106
+ value =~ /^(f|false|0)$/i ||
107
+ (value.respond_to? :empty? and value.empty?)
108
+ false
109
+ else
110
+ true
111
+ end
112
+ else
113
+ value
114
+ end
115
+ end
116
+ end