guise 0.2.3 → 0.3.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: a7c5c286fa539febf7ea6219aab2a407081b7b12
4
+ data.tar.gz: 848f2e32a8bcbde9fefc49fb30fc1728e8e7c989
5
+ SHA512:
6
+ metadata.gz: d114f4f75bcdfc5dad56b148292883812bdbd13c0153179cbee1347f62864fab1391f68b9c17f4bd59eeacd59ac299c4eb7e3498cc6f975d75e37b3c5cd12d9b
7
+ data.tar.gz: d7060c18f0b08727ec9a03d1bb96f6e835ea30b5ae915fa95012af4179832aa2e289de1d66a4e493510a2fd166dcc8fd11c4bf2e45d55c236fc82d69ae0d1d78
data/.travis.yml ADDED
@@ -0,0 +1,14 @@
1
+ rvm:
2
+ - 1.9.3
3
+ - 2.0.0
4
+ - 2.1.0
5
+ - jruby-19mode
6
+ gemfile:
7
+ - gemfiles/3.1.gemfile
8
+ - gemfiles/3.2.gemfile
9
+ - gemfiles/4.0.gemfile
10
+ install: 'bundle install -j 4'
11
+ script: 'bundle exec rake'
12
+ matrix:
13
+ allow_failures:
14
+ - rvm: jruby-19mode
data/Appraisals CHANGED
@@ -1,7 +1,14 @@
1
1
  appraise '3.1' do
2
- gem 'activerecord', '3.1.4'
2
+ gem 'activerecord', '~> 3.1'
3
+ gem 'activesupport', '~> 3.1'
3
4
  end
4
5
 
5
6
  appraise '3.2' do
6
- gem 'activerecord', '3.2.3'
7
+ gem 'activerecord', '~> 3.2'
8
+ gem 'activesupport', '~> 3.2'
9
+ end
10
+
11
+ appraise '4.0' do
12
+ gem 'activerecord', '~> 4.0'
13
+ gem 'activesupport', '~> 4.0'
7
14
  end
data/README.md CHANGED
@@ -1,11 +1,16 @@
1
1
  # guise
2
2
 
3
+ [![Build Status](https://travis-ci.org/ecbypi/guise.png?branch=master)](https://travis-ci.org/ecbypi/guise)
4
+ [![Code Climate](https://codeclimate.com/github/ecbypi/guise.png)](https://codeclimate.com/github/ecbypi/guise)
5
+
6
+
3
7
  An alternative to storing role resources in the database.
4
8
 
5
- guise delegates type information to a `has_many` association that stores the
6
- class names a resource can be instantiated as. In essence, it's similar to
7
- single table inheritance, but with multiple inheritances possible.
9
+ `guise` uses a `has_many` association to store type information instead of
10
+ using `has_many :through` or `has_and_belongs_to_many.` The `has_many` association
11
+ stores the role or type information as a string representing the class name.
8
12
 
13
+ If effect, `guise` enables 'multi-table-inheritance'.
9
14
 
10
15
  ## Installation
11
16
 
@@ -37,35 +42,28 @@ rails generate model user_role user:references title:string
37
42
  rake db:migrate
38
43
  ```
39
44
 
40
- Then add call the `has_guises` method in your model. This will setup the
41
- `has_many` association for you. It requires the name of the association and
42
- name of the column that the sublcass name will be stored in.
45
+ Then add `has_guises` to your model. This will setup the `has_many` association
46
+ for you. It requires the name of the association and name of the column that
47
+ the sublcass name will be stored in.
43
48
 
44
49
  ```ruby
45
50
  class User < ActiveRecord::Base
46
- has_guises :DeskWorker, :MailFowarder,
47
- :association => :user_roles,
48
- :attribute => :title
51
+ has_guises :DeskWorker, :MailForwarder, :association => :user_roles, :attribute => :title
49
52
  end
50
53
  ```
51
54
 
52
55
  This adds the following methods to the `User` class:
53
- * `:desk_workers` and `:mail_forwarders` scopes.
54
- * `:has_role?` that checks if a user is a particular type.
55
- * `:desk_worker?`, `:mail_forwarder` that proxy to `:has_role?`.
56
- * `:has_roles?` that checks if a user is of any of the types supplied.
57
-
58
- And creates classes `DeskWorker` and `MailForwarder` that:
59
- * Inherit from `User`.
60
- * Have default scopes for `:desk_workers` and `:mail_forwarders` respectively.
61
- * Create users with the right associated type.
62
-
56
+ * `:desk_workers` and `:mail_forwarders` model scopes.
57
+ * `:has_guise?` that checks if a user is a particular type.
58
+ * `:desk_worker?`, `:mail_forwarder` that proxy to `:has_guise?`.
59
+ * `:has_guises?` that checks if a user has records for all the types supplied.
60
+ * `:has_any_guises?` that checks if a user has records for any of the types supplied.
63
61
 
64
62
  To configure the other end of the association, add `guise_for`:
65
63
 
66
64
  ```ruby
67
65
  class UserRole < ActiveRecord::Base
68
- guise_for :user
66
+ guise_for :User
69
67
  end
70
68
  ```
71
69
 
@@ -74,6 +72,55 @@ This method does the following:
74
72
  * Validates the column storing the name of the guise in the list supplied is
75
73
  unique to the resource it belongs to and is one of the provided names.
76
74
 
75
+ To add a class for each guise, call `:guise_of` in a subclass:
76
+
77
+ ```ruby
78
+ class DeskWorker < User
79
+ guise_of :User
80
+ end
81
+ ```
82
+
83
+ This adds the following to the `DeskWorker` class:
84
+
85
+ ```ruby
86
+ class DeskWorker < User
87
+ default_scope -> { joins(:user_roles).where(user_roles: { title: 'DeskWorker'}) }
88
+
89
+ after_initialize do
90
+ self.guises.build(title: 'DeskWorker')
91
+ end
92
+
93
+ after_create do
94
+ self.guises.create(title: 'DeskWorker')
95
+ end
96
+ end
97
+ ```
98
+
99
+ To scope the association class to a guise, use `scoped_guise_for`. The name of
100
+ the class must be the guise it represents combined with the name of the parent
101
+ class.
102
+
103
+ ```ruby
104
+ class DeskWorkerUserRole < UserRole
105
+ scoped_guise_for :User
106
+ end
107
+ ```
108
+
109
+ This sets up the class as follows:
110
+
111
+ ```ruby
112
+ class DeskWorkerUserRole < UserRole
113
+ default_scope -> { where(title: 'DeskWorker') }
114
+
115
+ after_initialize do
116
+ self.title = 'DeskWorker'
117
+ end
118
+
119
+ before_create do
120
+ self.title = 'DeskWorker'
121
+ end
122
+ end
123
+ ```
77
124
 
78
125
  ### Customization
79
126
 
@@ -91,7 +138,7 @@ class Person < ActiveRecord::Base
91
138
  end
92
139
 
93
140
  class JobTitle < ActiveRecord::Base
94
- guise_for :person,
141
+ guise_for :Person,
95
142
  :foreign_key => :employee_id,
96
143
  :validate => false # skip setting up validations
97
144
  end
data/Rakefile CHANGED
@@ -8,3 +8,5 @@ desc "Run specs"
8
8
  RSpec::Core::RakeTask.new('spec') do |task|
9
9
  task.pattern = 'spec/**/*_spec.rb'
10
10
  end
11
+
12
+ task :default => :spec
data/gemfiles/3.1.gemfile CHANGED
@@ -2,6 +2,7 @@
2
2
 
3
3
  source "https://rubygems.org"
4
4
 
5
- gem "activerecord", "3.1.4"
5
+ gem "activerecord", "~> 3.1"
6
+ gem "activesupport", "~> 3.1"
6
7
 
7
8
  gemspec :path=>"../"
@@ -1,56 +1,66 @@
1
1
  PATH
2
- remote: /Users/edd_d/dev/guise
2
+ remote: ../
3
3
  specs:
4
- guise (0.2.0)
5
- activerecord (~> 3.1)
6
- activesupport (~> 3.1)
4
+ guise (0.3.0)
5
+ activerecord (>= 3.1, < 4.1)
6
+ activesupport (>= 3.1, < 4.1)
7
7
 
8
8
  GEM
9
9
  remote: https://rubygems.org/
10
10
  specs:
11
- activemodel (3.1.4)
12
- activesupport (= 3.1.4)
11
+ activemodel (3.2.16)
12
+ activesupport (= 3.2.16)
13
13
  builder (~> 3.0.0)
14
- i18n (~> 0.6)
15
- activerecord (3.1.4)
16
- activemodel (= 3.1.4)
17
- activesupport (= 3.1.4)
18
- arel (~> 2.2.3)
14
+ activerecord (3.2.16)
15
+ activemodel (= 3.2.16)
16
+ activesupport (= 3.2.16)
17
+ arel (~> 3.0.2)
19
18
  tzinfo (~> 0.3.29)
20
- activesupport (3.1.4)
19
+ activesupport (3.2.16)
20
+ i18n (~> 0.6, >= 0.6.4)
21
21
  multi_json (~> 1.0)
22
- appraisal (0.4.1)
22
+ appraisal (0.5.2)
23
23
  bundler
24
24
  rake
25
- arel (2.2.3)
26
- builder (3.0.0)
27
- diff-lcs (1.1.3)
28
- factory_girl (3.2.0)
25
+ arel (3.0.3)
26
+ builder (3.0.4)
27
+ coderay (1.1.0)
28
+ diff-lcs (1.2.5)
29
+ factory_girl (4.4.0)
29
30
  activesupport (>= 3.0.0)
30
- i18n (0.6.0)
31
- multi_json (1.3.4)
32
- rake (0.9.2.2)
33
- rspec (2.10.0)
34
- rspec-core (~> 2.10.0)
35
- rspec-expectations (~> 2.10.0)
36
- rspec-mocks (~> 2.10.0)
37
- rspec-core (2.10.0)
38
- rspec-expectations (2.10.0)
39
- diff-lcs (~> 1.1.3)
40
- rspec-mocks (2.10.1)
41
- shoulda-matchers (1.1.0)
31
+ i18n (0.6.9)
32
+ method_source (0.8.2)
33
+ multi_json (1.8.4)
34
+ pry (0.9.12.6)
35
+ coderay (~> 1.0)
36
+ method_source (~> 0.8)
37
+ slop (~> 3.4)
38
+ rake (10.1.1)
39
+ rspec (2.14.1)
40
+ rspec-core (~> 2.14.0)
41
+ rspec-expectations (~> 2.14.0)
42
+ rspec-mocks (~> 2.14.0)
43
+ rspec-core (2.14.7)
44
+ rspec-expectations (2.14.4)
45
+ diff-lcs (>= 1.1.3, < 2.0)
46
+ rspec-mocks (2.14.4)
47
+ shoulda-matchers (2.5.0)
42
48
  activesupport (>= 3.0.0)
43
- sqlite3 (1.3.6)
44
- tzinfo (0.3.33)
49
+ slop (3.4.7)
50
+ sqlite3 (1.3.8)
51
+ tzinfo (0.3.38)
45
52
 
46
53
  PLATFORMS
47
54
  ruby
48
55
 
49
56
  DEPENDENCIES
50
- activerecord (= 3.1.4)
51
- appraisal
52
- factory_girl (~> 3.2)
57
+ activerecord (~> 3.1)
58
+ activesupport (~> 3.1)
59
+ appraisal (~> 0.5)
60
+ factory_girl (~> 4.4)
53
61
  guise!
54
- rspec (~> 2.9)
55
- shoulda-matchers (~> 1.1)
56
- sqlite3 (~> 1.3.3)
62
+ pry (~> 0.9)
63
+ rake (~> 10.1)
64
+ rspec (~> 2.14)
65
+ shoulda-matchers (~> 2.5)
66
+ sqlite3 (~> 1.3)
data/gemfiles/3.2.gemfile CHANGED
@@ -2,6 +2,7 @@
2
2
 
3
3
  source "https://rubygems.org"
4
4
 
5
- gem "activerecord", "3.2.3"
5
+ gem "activerecord", "~> 3.2"
6
+ gem "activesupport", "~> 3.2"
6
7
 
7
8
  gemspec :path=>"../"
@@ -1,56 +1,66 @@
1
1
  PATH
2
- remote: /Users/edd_d/dev/guise
2
+ remote: ../
3
3
  specs:
4
- guise (0.2.0)
5
- activerecord (~> 3.1)
6
- activesupport (~> 3.1)
4
+ guise (0.3.0)
5
+ activerecord (>= 3.1, < 4.1)
6
+ activesupport (>= 3.1, < 4.1)
7
7
 
8
8
  GEM
9
9
  remote: https://rubygems.org/
10
10
  specs:
11
- activemodel (3.2.3)
12
- activesupport (= 3.2.3)
11
+ activemodel (3.2.16)
12
+ activesupport (= 3.2.16)
13
13
  builder (~> 3.0.0)
14
- activerecord (3.2.3)
15
- activemodel (= 3.2.3)
16
- activesupport (= 3.2.3)
14
+ activerecord (3.2.16)
15
+ activemodel (= 3.2.16)
16
+ activesupport (= 3.2.16)
17
17
  arel (~> 3.0.2)
18
18
  tzinfo (~> 0.3.29)
19
- activesupport (3.2.3)
20
- i18n (~> 0.6)
19
+ activesupport (3.2.16)
20
+ i18n (~> 0.6, >= 0.6.4)
21
21
  multi_json (~> 1.0)
22
- appraisal (0.4.1)
22
+ appraisal (0.5.2)
23
23
  bundler
24
24
  rake
25
- arel (3.0.2)
26
- builder (3.0.0)
27
- diff-lcs (1.1.3)
28
- factory_girl (3.2.0)
25
+ arel (3.0.3)
26
+ builder (3.0.4)
27
+ coderay (1.1.0)
28
+ diff-lcs (1.2.5)
29
+ factory_girl (4.4.0)
29
30
  activesupport (>= 3.0.0)
30
- i18n (0.6.0)
31
- multi_json (1.3.4)
32
- rake (0.9.2.2)
33
- rspec (2.10.0)
34
- rspec-core (~> 2.10.0)
35
- rspec-expectations (~> 2.10.0)
36
- rspec-mocks (~> 2.10.0)
37
- rspec-core (2.10.0)
38
- rspec-expectations (2.10.0)
39
- diff-lcs (~> 1.1.3)
40
- rspec-mocks (2.10.1)
41
- shoulda-matchers (1.1.0)
31
+ i18n (0.6.9)
32
+ method_source (0.8.2)
33
+ multi_json (1.8.4)
34
+ pry (0.9.12.6)
35
+ coderay (~> 1.0)
36
+ method_source (~> 0.8)
37
+ slop (~> 3.4)
38
+ rake (10.1.1)
39
+ rspec (2.14.1)
40
+ rspec-core (~> 2.14.0)
41
+ rspec-expectations (~> 2.14.0)
42
+ rspec-mocks (~> 2.14.0)
43
+ rspec-core (2.14.7)
44
+ rspec-expectations (2.14.4)
45
+ diff-lcs (>= 1.1.3, < 2.0)
46
+ rspec-mocks (2.14.4)
47
+ shoulda-matchers (2.5.0)
42
48
  activesupport (>= 3.0.0)
43
- sqlite3 (1.3.6)
44
- tzinfo (0.3.33)
49
+ slop (3.4.7)
50
+ sqlite3 (1.3.8)
51
+ tzinfo (0.3.38)
45
52
 
46
53
  PLATFORMS
47
54
  ruby
48
55
 
49
56
  DEPENDENCIES
50
- activerecord (= 3.2.3)
51
- appraisal
52
- factory_girl (~> 3.2)
57
+ activerecord (~> 3.2)
58
+ activesupport (~> 3.2)
59
+ appraisal (~> 0.5)
60
+ factory_girl (~> 4.4)
53
61
  guise!
54
- rspec (~> 2.9)
55
- shoulda-matchers (~> 1.1)
56
- sqlite3 (~> 1.3.3)
62
+ pry (~> 0.9)
63
+ rake (~> 10.1)
64
+ rspec (~> 2.14)
65
+ shoulda-matchers (~> 2.5)
66
+ sqlite3 (~> 1.3)
@@ -0,0 +1,8 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "activerecord", "~> 4.0"
6
+ gem "activesupport", "~> 4.0"
7
+
8
+ gemspec :path=>"../"
@@ -0,0 +1,74 @@
1
+ PATH
2
+ remote: ../
3
+ specs:
4
+ guise (0.3.0)
5
+ activerecord (>= 3.1, < 4.1)
6
+ activesupport (>= 3.1, < 4.1)
7
+
8
+ GEM
9
+ remote: https://rubygems.org/
10
+ specs:
11
+ activemodel (4.0.3)
12
+ activesupport (= 4.0.3)
13
+ builder (~> 3.1.0)
14
+ activerecord (4.0.3)
15
+ activemodel (= 4.0.3)
16
+ activerecord-deprecated_finders (~> 1.0.2)
17
+ activesupport (= 4.0.3)
18
+ arel (~> 4.0.0)
19
+ activerecord-deprecated_finders (1.0.3)
20
+ activesupport (4.0.3)
21
+ i18n (~> 0.6, >= 0.6.4)
22
+ minitest (~> 4.2)
23
+ multi_json (~> 1.3)
24
+ thread_safe (~> 0.1)
25
+ tzinfo (~> 0.3.37)
26
+ appraisal (0.5.2)
27
+ bundler
28
+ rake
29
+ arel (4.0.2)
30
+ atomic (1.1.14)
31
+ builder (3.1.4)
32
+ coderay (1.1.0)
33
+ diff-lcs (1.2.5)
34
+ factory_girl (4.4.0)
35
+ activesupport (>= 3.0.0)
36
+ i18n (0.6.9)
37
+ method_source (0.8.2)
38
+ minitest (4.7.5)
39
+ multi_json (1.8.4)
40
+ pry (0.9.12.6)
41
+ coderay (~> 1.0)
42
+ method_source (~> 0.8)
43
+ slop (~> 3.4)
44
+ rake (10.1.1)
45
+ rspec (2.14.1)
46
+ rspec-core (~> 2.14.0)
47
+ rspec-expectations (~> 2.14.0)
48
+ rspec-mocks (~> 2.14.0)
49
+ rspec-core (2.14.7)
50
+ rspec-expectations (2.14.4)
51
+ diff-lcs (>= 1.1.3, < 2.0)
52
+ rspec-mocks (2.14.4)
53
+ shoulda-matchers (2.5.0)
54
+ activesupport (>= 3.0.0)
55
+ slop (3.4.7)
56
+ sqlite3 (1.3.8)
57
+ thread_safe (0.1.3)
58
+ atomic
59
+ tzinfo (0.3.38)
60
+
61
+ PLATFORMS
62
+ ruby
63
+
64
+ DEPENDENCIES
65
+ activerecord (~> 4.0)
66
+ activesupport (~> 4.0)
67
+ appraisal (~> 0.5)
68
+ factory_girl (~> 4.4)
69
+ guise!
70
+ pry (~> 0.9)
71
+ rake (~> 10.1)
72
+ rspec (~> 2.14)
73
+ shoulda-matchers (~> 2.5)
74
+ sqlite3 (~> 1.3)
data/guise.gemspec CHANGED
@@ -17,12 +17,23 @@ Gem::Specification.new do |gem|
17
17
  gem.name = "guise"
18
18
  gem.require_paths = ["lib"]
19
19
  gem.version = Guise::VERSION
20
+ gem.license = 'MIT'
20
21
 
21
- gem.add_dependency "activerecord", "~> 3.1"
22
- gem.add_dependency "activesupport", "~> 3.1"
23
- gem.add_development_dependency "rspec", "~> 2.9"
24
- gem.add_development_dependency "sqlite3", "~> 1.3.3"
25
- gem.add_development_dependency "factory_girl", "~> 3.2"
26
- gem.add_development_dependency "shoulda-matchers", "~> 1.1"
27
- gem.add_development_dependency "appraisal"
22
+ gem.required_ruby_version = '>= 1.9.3'
23
+
24
+ gem.add_dependency "activerecord", ">= 3.1", "< 4.1"
25
+ gem.add_dependency "activesupport", ">= 3.1", "< 4.1"
26
+ gem.add_development_dependency 'rake', '~> 10.1'
27
+ gem.add_development_dependency "rspec", "~> 2.14"
28
+ gem.add_development_dependency "factory_girl", "~> 4.4"
29
+ gem.add_development_dependency "shoulda-matchers", "~> 2.5"
30
+ gem.add_development_dependency "appraisal", '~> 0.5'
31
+ gem.add_development_dependency 'pry', '~> 0.9'
32
+
33
+ if RUBY_PLATFORM == 'java'
34
+ gem.add_development_dependency 'activerecord-jdbcsqlite3-adapter'
35
+ gem.add_development_dependency 'jdbc-sqlite3'
36
+ else
37
+ gem.add_development_dependency 'sqlite3', '~> 1.3'
38
+ end
28
39
  end
@@ -0,0 +1,28 @@
1
+ module Guise
2
+ class Callback
3
+ def initialize(guise, attribute)
4
+ @guise = guise
5
+ @attribute = attribute
6
+ end
7
+ end
8
+
9
+ class SourceCallback < Callback
10
+ def after_initialize(record)
11
+ record.guises.build(@attribute => @guise)
12
+ end
13
+
14
+ def after_create(record)
15
+ record.guises.create(@attribute => @guise)
16
+ end
17
+ end
18
+
19
+ class AssociationCallback < Callback
20
+ def after_initialize(record)
21
+ record.assign_attributes(@attribute => @guise)
22
+ end
23
+
24
+ def before_create(record)
25
+ record.assign_attributes(@attribute => @guise)
26
+ end
27
+ end
28
+ end
@@ -1,32 +1,31 @@
1
+ require 'active_support/concern'
2
+
1
3
  module Guise
2
4
  module Introspection
5
+ extend ActiveSupport::Concern
3
6
 
4
- def has_role?(name)
5
- name = name.to_s.classify
7
+ def has_guise?(value)
8
+ value = value.to_s.classify
6
9
 
7
- if !self.class.guises.include?(name)
8
- raise NameError, "no such guise #{name}"
10
+ unless guise_options[:names].any? { |name| name == value }
11
+ raise ArgumentError, "no such guise #{value}"
9
12
  end
10
13
 
11
- guises.map(&guise_attribute).include?(name)
14
+ guises.any? { |guise| guise[guise_options[:attribute]] == value }
12
15
  end
13
16
 
14
- def has_any_roles?(*names)
15
- names.map(&method(:has_role?)).any?
17
+ def has_any_guises?(*values)
18
+ values.any? { |value| has_guise?(value) }
16
19
  end
17
20
 
18
- def has_roles?(*names)
19
- names.map(&method(:has_role?)).all?
21
+ def has_guises?(*values)
22
+ values.all? { |value| has_guise?(value) }
20
23
  end
21
24
 
22
- protected
23
-
24
- def guise_attribute
25
- self.class.guise_attribute
26
- end
25
+ private
27
26
 
28
- def guise_table
29
- self.class.guise_table
27
+ def guise_options
28
+ Guise.registry[self.class.table_name.classify]
30
29
  end
31
30
  end
32
31
  end
File without changes