rails-properties 3.4.3

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,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 7be3c5bb1390b030f3cf3b0bd14a0b7227806704
4
+ data.tar.gz: bf1b88871e3f28897b72a33e305d329ea2041e4e
5
+ SHA512:
6
+ metadata.gz: a9f6063f9fd8e8f0b68b8f3bb5b4d1c82cd6551e856d52b05e5a42f45a1a965d25f52942226cb528fb0aef9d50b8ac81af11daf5e5c311fb7ad01997cde81dc5
7
+ data.tar.gz: 41c8f6000e5ab99749548fac88738720a69c86a83241ef43386e2f2183a706eaa84507c9941dddcaeed5d92d71d7c77cb6aaf5ae58e99449527822cb37026594
@@ -0,0 +1,5 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
5
+ coverage/*
@@ -0,0 +1,74 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.9.3
4
+ - 2.0.0
5
+ - 2.1.10
6
+ - 2.2.9
7
+ - 2.3.6
8
+ - 2.4.3
9
+ - 2.5.0
10
+ gemfile:
11
+ - ci/Gemfile-rails-3-1
12
+ - ci/Gemfile-rails-3-2
13
+ - ci/Gemfile-rails-4-0
14
+ - ci/Gemfile-rails-4-1
15
+ - ci/Gemfile-rails-4-2
16
+ - ci/Gemfile-rails-5-0
17
+ - ci/Gemfile-rails-5-1
18
+ - ci/Gemfile-rails-5-2
19
+ matrix:
20
+ include:
21
+ - rvm: 2.2.9
22
+ gemfile: ci/Gemfile-rails-4-0
23
+ env: PROTECTED_ATTRIBUTES=true
24
+ - rvm: 2.2.9
25
+ gemfile: ci/Gemfile-rails-4-1
26
+ env: PROTECTED_ATTRIBUTES=true
27
+ - rvm: 2.2.9
28
+ gemfile: ci/Gemfile-rails-4-2
29
+ env: PROTECTED_ATTRIBUTES=true
30
+ exclude:
31
+ - rvm: 1.9.3
32
+ gemfile: ci/Gemfile-rails-5-0
33
+ - rvm: 1.9.3
34
+ gemfile: ci/Gemfile-rails-5-1
35
+ - rvm: 1.9.3
36
+ gemfile: ci/Gemfile-rails-5-2
37
+ - rvm: 2.0.0
38
+ gemfile: ci/Gemfile-rails-5-0
39
+ - rvm: 2.0.0
40
+ gemfile: ci/Gemfile-rails-5-1
41
+ - rvm: 2.0.0
42
+ gemfile: ci/Gemfile-rails-5-2
43
+ - rvm: 2.1.10
44
+ gemfile: ci/Gemfile-rails-5-0
45
+ - rvm: 2.1.10
46
+ gemfile: ci/Gemfile-rails-5-1
47
+ - rvm: 2.1.10
48
+ gemfile: ci/Gemfile-rails-5-2
49
+ - rvm: 2.2.9
50
+ gemfile: ci/Gemfile-rails-3-1
51
+ - rvm: 2.3.6
52
+ gemfile: ci/Gemfile-rails-3-1
53
+ - rvm: 2.4.3
54
+ gemfile: ci/Gemfile-rails-3-1
55
+ - rvm: 2.5.0
56
+ gemfile: ci/Gemfile-rails-3-1
57
+ - rvm: 2.2.9
58
+ gemfile: ci/Gemfile-rails-3-2
59
+ - rvm: 2.3.6
60
+ gemfile: ci/Gemfile-rails-3-2
61
+ - rvm: 2.4.3
62
+ gemfile: ci/Gemfile-rails-3-2
63
+ - rvm: 2.4.3
64
+ gemfile: ci/Gemfile-rails-4-0
65
+ - rvm: 2.4.3
66
+ gemfile: ci/Gemfile-rails-4-1
67
+ - rvm: 2.5.0
68
+ gemfile: ci/Gemfile-rails-3-2
69
+ - rvm: 2.5.0
70
+ gemfile: ci/Gemfile-rails-4-0
71
+ - rvm: 2.5.0
72
+ gemfile: ci/Gemfile-rails-4-1
73
+ before_install: gem update bundler
74
+ sudo: false
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in rails-properties.gemspec
4
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012-2018 Georg Ledermann
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,135 @@
1
+ # Properties for Rails
2
+
3
+ Ruby gem to handle properties for ActiveRecord instances by storing them as serialized Hash in a separate database table. Namespaces and defaults included.
4
+
5
+ ## Requirements
6
+
7
+ * Ruby 1.9.3 or newer
8
+ * Rails 3.1 or newer (including Rails 5.2)
9
+
10
+
11
+ ## Installation
12
+
13
+ Include the gem in your Gemfile and run `bundle` to install it:
14
+
15
+ ```ruby
16
+ gem 'rails-properties'
17
+ ```
18
+
19
+ Generate and run the migration:
20
+
21
+ ```shell
22
+ rails g rails_properties:migration
23
+ rake db:migrate
24
+ ```
25
+
26
+
27
+ ## Usage
28
+
29
+ ### Define properties
30
+
31
+ ```ruby
32
+ class User < ActiveRecord::Base
33
+ has_properties do |s|
34
+ s.key :dashboard, :defaults => { :theme => 'blue', :view => 'monthly', :filter => false }
35
+ s.key :calendar, :defaults => { :scope => 'company'}
36
+ end
37
+ end
38
+ ```
39
+
40
+ If no defaults are needed, a simplified syntax can be used:
41
+
42
+ ```ruby
43
+ class User < ActiveRecord::Base
44
+ has_properties :dashboard, :calendar
45
+ end
46
+ ```
47
+
48
+ Every property is handled by the class `RailsProperties::PropertyObject`. You can use your own class, e.g. for validations:
49
+
50
+ ```ruby
51
+ class Project < ActiveRecord::Base
52
+ has_properties :info, :class_name => 'ProjectPropertyObject'
53
+ end
54
+
55
+ class ProjectPropertyObject < RailsProperties::PropertyObject
56
+ validate do
57
+ unless self.owner_name.present? && self.owner_name.is_a?(String)
58
+ errors.add(:base, "Owner name is missing")
59
+ end
60
+ end
61
+ end
62
+ ```
63
+
64
+ ### Set properties
65
+
66
+ ```ruby
67
+ user = User.find(1)
68
+ user.properties(:dashboard).theme = 'black'
69
+ user.properties(:calendar).scope = 'all'
70
+ user.properties(:calendar).display = 'daily'
71
+ user.save! # saves new or changed properties, too
72
+ ```
73
+
74
+ or
75
+
76
+ ```ruby
77
+ user = User.find(1)
78
+ user.properties(:dashboard).update_attributes! :theme => 'black'
79
+ user.properties(:calendar).update_attributes! :scope => 'all', :display => 'daily'
80
+ ```
81
+
82
+
83
+ ### Get properties
84
+
85
+ ```ruby
86
+ user = User.find(1)
87
+ user.properties(:dashboard).theme
88
+ # => 'black
89
+
90
+ user.properties(:dashboard).view
91
+ # => 'monthly' (it's the default)
92
+
93
+ user.properties(:calendar).scope
94
+ # => 'all'
95
+ ```
96
+
97
+ ### Delete properties
98
+
99
+ ```ruby
100
+ user = User.find(1)
101
+ user.properties(:dashboard).update_attributes! :theme => nil
102
+
103
+ user.properties(:dashboard).view = nil
104
+ user.properties(:dashboard).save!
105
+ ```
106
+
107
+ ### Using scopes
108
+
109
+ ```ruby
110
+ User.with_properties
111
+ # => all users having any property
112
+
113
+ User.without_properties
114
+ # => all users without having any property
115
+
116
+ User.with_properties_for(:calendar)
117
+ # => all users having a property for 'calender'
118
+
119
+ User.without_properties_for(:calendar)
120
+ # => all users without having properties for 'calendar'
121
+ ```
122
+
123
+ ### Eager Loading
124
+ ```ruby
125
+ User.includes(:property_objects)
126
+ # => Eager load property_objects when querying many users
127
+ ```
128
+
129
+ ## License
130
+
131
+ MIT License
132
+
133
+ Copyright (c) 2012-2018 [Georg Ledermann](http://www.georg-ledermann.de)
134
+
135
+ This gem is a rename of [rails-settings](https://github.com/ledermann/rails-settings) by [Georg Ledermann](https://github.com/ledermann)
@@ -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,5 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'activerecord', '~> 3.1.12'
4
+
5
+ gemspec :path => "../"
@@ -0,0 +1,5 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'activerecord', '~> 3.2.22'
4
+
5
+ gemspec :path => "../"
@@ -0,0 +1,6 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'activerecord', '~> 4.0.13'
4
+ gem 'protected_attributes' if ENV['PROTECTED_ATTRIBUTES'] == 'true'
5
+
6
+ gemspec :path => "../"
@@ -0,0 +1,6 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'activerecord', '~> 4.1.10'
4
+ gem 'protected_attributes' if ENV['PROTECTED_ATTRIBUTES'] == 'true'
5
+
6
+ gemspec :path => "../"
@@ -0,0 +1,6 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'activerecord', '~> 4.2.1'
4
+ gem 'protected_attributes' if ENV['PROTECTED_ATTRIBUTES'] == 'true'
5
+
6
+ gemspec :path => "../"
@@ -0,0 +1,5 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'activerecord', '~> 5.0.0'
4
+
5
+ gemspec :path => "../"
@@ -0,0 +1,5 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'activerecord', '~> 5.1.0'
4
+
5
+ gemspec :path => "../"
@@ -0,0 +1,5 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'activerecord', '~> 5.2.0.rc1'
4
+
5
+ gemspec :path => "../"
@@ -0,0 +1,23 @@
1
+ require 'rails/generators'
2
+ require 'rails/generators/migration'
3
+
4
+ module RailsProperties
5
+ class MigrationGenerator < Rails::Generators::Base
6
+ include Rails::Generators::Migration
7
+
8
+ desc "Generates migration for rails-properties"
9
+ source_root File.expand_path('../templates', __FILE__)
10
+
11
+ def create_migration_file
12
+ migration_template 'migration.rb', 'db/migrate/rails_properties_migration.rb'
13
+ end
14
+
15
+ def self.next_migration_number(dirname)
16
+ if ActiveRecord::Base.timestamped_migrations
17
+ Time.now.utc.strftime("%Y%m%d%H%M%S")
18
+ else
19
+ "%.3d" % (current_migration_number(dirname) + 1)
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,21 @@
1
+ MIGRATION_BASE_CLASS = if ActiveRecord::VERSION::MAJOR >= 5
2
+ ActiveRecord::Migration[5.0]
3
+ else
4
+ ActiveRecord::Migration
5
+ end
6
+
7
+ class RailsPropertiesMigration < MIGRATION_BASE_CLASS
8
+ def self.up
9
+ create_table :properties do |t|
10
+ t.string :var, :null => false
11
+ t.text :value
12
+ t.references :target, :null => false, :polymorphic => true
13
+ t.timestamps :null => true
14
+ end
15
+ add_index :properties, [ :target_type, :target_id, :var ], :unique => true
16
+ end
17
+
18
+ def self.down
19
+ drop_table :properties
20
+ end
21
+ end
@@ -0,0 +1,23 @@
1
+ module RailsProperties
2
+ # In Rails 3, attributes can be protected by `attr_accessible` and `attr_protected`
3
+ # In Rails 4, attributes can be protected by using the gem `protected_attributes`
4
+ # In Rails 5, protecting attributes is obsolete (there are `StrongParameters` only)
5
+ def self.can_protect_attributes?
6
+ (ActiveRecord::VERSION::MAJOR == 3) || defined?(ProtectedAttributes)
7
+ end
8
+ end
9
+
10
+ require 'rails-properties/property_object'
11
+ require 'rails-properties/configuration'
12
+ require 'rails-properties/base'
13
+ require 'rails-properties/scopes'
14
+
15
+ ActiveRecord::Base.class_eval do
16
+ def self.has_properties(*args, &block)
17
+ RailsProperties::Configuration.new(*args.unshift(self), &block)
18
+
19
+ include RailsProperties::Base
20
+ extend RailsProperties::Scopes
21
+ end
22
+ end
23
+
@@ -0,0 +1,48 @@
1
+ module RailsProperties
2
+ module Base
3
+ def self.included(base)
4
+ base.class_eval do
5
+ has_many :property_objects,
6
+ :as => :target,
7
+ :autosave => true,
8
+ :dependent => :delete_all,
9
+ :class_name => self.property_object_class_name
10
+
11
+ def properties(var)
12
+ raise ArgumentError unless var.is_a?(Symbol)
13
+ raise ArgumentError.new("Unknown key: #{var}") unless self.class.default_properties[var]
14
+
15
+ if RailsProperties.can_protect_attributes?
16
+ property_objects.detect { |s| s.var == var.to_s } || property_objects.build({ :var => var.to_s }, :without_protection => true)
17
+ else
18
+ property_objects.detect { |s| s.var == var.to_s } || property_objects.build(:var => var.to_s, :target => self)
19
+ end
20
+ end
21
+
22
+ def properties=(value)
23
+ if value.nil?
24
+ property_objects.each(&:mark_for_destruction)
25
+ else
26
+ raise ArgumentError
27
+ end
28
+ end
29
+
30
+ def properties?(var=nil)
31
+ if var.nil?
32
+ property_objects.any? { |property_object| !property_object.marked_for_destruction? && property_object.value.present? }
33
+ else
34
+ properties(var).value.present?
35
+ end
36
+ end
37
+
38
+ def to_properties_hash
39
+ properties_hash = self.class.default_properties.dup
40
+ properties_hash.each do |var, vals|
41
+ properties_hash[var] = properties_hash[var].merge(properties(var.to_sym).value)
42
+ end
43
+ properties_hash
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,32 @@
1
+ module RailsProperties
2
+ class Configuration
3
+ def initialize(*args, &block)
4
+ options = args.extract_options!
5
+ klass = args.shift
6
+ keys = args
7
+
8
+ raise ArgumentError unless klass
9
+
10
+ @klass = klass
11
+ @klass.class_attribute :default_properties, :property_object_class_name
12
+ @klass.default_properties = {}
13
+ @klass.property_object_class_name = options[:class_name] || 'RailsProperties::PropertyObject'
14
+
15
+ if block_given?
16
+ yield(self)
17
+ else
18
+ keys.each do |k|
19
+ key(k)
20
+ end
21
+ end
22
+
23
+ raise ArgumentError.new('has_properties: No keys defined') if @klass.default_properties.blank?
24
+ end
25
+
26
+ def key(name, options={})
27
+ raise ArgumentError.new("has_properties: Symbol expected, but got a #{name.class}") unless name.is_a?(Symbol)
28
+ raise ArgumentError.new("has_properties: Option :defaults expected, but got #{options.keys.join(', ')}") unless options.blank? || (options.keys == [:defaults])
29
+ @klass.default_properties[name] = (options[:defaults] || {}).stringify_keys.freeze
30
+ end
31
+ end
32
+ end