company_scope 0.1.2 → 0.1.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 736068a8a448f00bbc6691173a4a6fa89c086d41
4
- data.tar.gz: ed3357ed9447e8018760334dad8b5aa0febe463c
3
+ metadata.gz: e23f0f1665e578c9287a203ebff02717f204dfe4
4
+ data.tar.gz: 83ba3007224cc8c97f5003263efc18e97ee7e111
5
5
  SHA512:
6
- metadata.gz: 9b70cb263376ee416321a517c0f2c72653cee0cdfc59f4e3ffed8bb9e41454c38b8b3638b42e4c85695c797fe494b7db3eb0e58138cfdfcf398e470aebcda3fa
7
- data.tar.gz: ad8b3a6fe5b67ba1a8e4a114ecf7106582b1fb3cc94ca945dcff594f39b67838c49e4c1957716b89728b324d5274cb0803ce0bf2ab46ebfc696b9896bcdea4a6
6
+ metadata.gz: e0835d33a937cb22c23d5fa021f644470050ffbd4f160e0096f28a018cb902ace3bb83b44cd55b5c615194d7302949a7d5760999f8fe4a8771fea1f0514035f5
7
+ data.tar.gz: d73b5642d099a30aec593f7b4c124b766312237b20c2cb4838fbea1d84bb6216fed20305d1e0d1f46ce706a11003ef7ec06aab0ed56997382bda1e562bbf7f28
data/README.md CHANGED
@@ -41,15 +41,54 @@ There are three main steps in adding multi-tenancy/company to your app with comp
41
41
  ### Decide on a process of determining the company/account ###
42
42
 
43
43
  In the current version a helper_method called "current_company" is added to the Controller,
44
- where you add the method "company_setup". You have therefore two choices. Either you use your
45
- own process to set the instance of "Company" into "request.env".
44
+ where you add the method "company_setup". You have therefore two choices. Either you use the
45
+ company_scope gem process included Rack Middleware or your own process to set the instance
46
+ of "Company" into "request.env".
47
+
48
+ The included Rack Middleware can be inserted into the Rails Application stack in the config
49
+ section of 'application.rb'.
50
+
51
+ ```ruby
52
+ module YourRailsApp
53
+ class Application < Rails::Application
54
+ ...
55
+ # - add some Rack middleware to detect the company_name from the subdomain
56
+ config.middleware.insert_after Rack::Sendfile, Rack::MultiCompany, :company
57
+ ...
58
+ end
59
+ end
60
+ ```
61
+
62
+ The parameter in the example above needs to be a symbol of the model of your application
63
+ that will act as the account i.e. company, tenant etc.
64
+
65
+ The domain 'lvh.me' points to 127.0.0.1 and is therefore an ideal candidate for using with local development and subdomains since they will also all point to your localhost.
66
+
67
+ [See here for info](http://stackoverflow.com/questions/12983072/rails-3-subdomain-testing-using-lvh-me)
68
+
69
+ NB: The middleware currently uses a regex to ensure the domain name can only obtain the following:
70
+
71
+ * A-Z
72
+ * a-z
73
+ * 0-9
74
+
75
+ The middleware then uses the column called "class_name"_name i.e. "company_name"
76
+
77
+ No spaces or special characters are permitted and the name is also upcased - which needs to be handled
78
+ by the model you use for scoping! This just keeps the name clean and simple.
79
+ We would strongly recommend you to have a proper index on the company
80
+
81
+ The method below is included in the Controller stack (see notes further down), and retrieves
82
+ the company object the request object. The Rack Middleware "Rack::MultiCompany" injects this
83
+ object into each request!
46
84
 
47
85
  ```ruby
48
86
  def current_company
49
87
  request.env["COMPANY_ID"]
50
88
  end
51
89
  ```
52
- An example of this is to use "Rack Middleware" - see the method excerpt below:
90
+
91
+ An example of how the gem does this using "Rack Middleware" - is in the excerpt below:
53
92
 
54
93
  ```ruby
55
94
  def call(env)
@@ -61,9 +100,6 @@ def call(env)
61
100
  end
62
101
  ```
63
102
 
64
- The next version of "company_scope", will have the Rack::Middleware call integrated and the
65
- ability to opt out of using it.
66
-
67
103
  Alternatively you can use your own process for determining the "current_company" and override this
68
104
  method in your application controller, providing you declare this after the "company_setup" method,
69
105
  which is detailed in the next step.
@@ -119,6 +155,9 @@ class Company < ActiveRecord::Base
119
155
  end
120
156
  ```
121
157
 
158
+ The gem also injects
159
+
160
+
122
161
  * Each class to be scoped needs to have the "acts_as_company :account" method. The parameter ":account"
123
162
  defaults to :company if left blank. This can be any class/name of your choosing - the parameter needs
124
163
  to be a underscored version of the Class name as a symbol.
@@ -29,6 +29,7 @@ Gem::Specification.new do |spec|
29
29
  spec.add_development_dependency "rake", "~> 10.0"
30
30
  #
31
31
  # - gem related ones
32
+ spec.add_development_dependency 'rack'
32
33
  spec.add_development_dependency 'rspec'
33
34
  spec.add_development_dependency 'rspec-given'
34
35
  spec.add_development_dependency 'rspec-collection_matchers'
@@ -10,6 +10,9 @@ module CompanyScope
10
10
  module GuardianClassMethods
11
11
  #
12
12
  def acts_as_guardian
13
+ #
14
+ #puts "\n\n\n Class Name: #{self.class.to_s.downcase}\n\n\n"
15
+ #validates_uniqueness_of "#{self.class.to_s.downcase}_name".to_sym #:company_name
13
16
  #
14
17
  def current_id=(id)
15
18
  RequestStore.store[:default_scope_company_id] = id
@@ -1,3 +1,3 @@
1
1
  module CompanyScope
2
- VERSION = "0.1.2"
2
+ VERSION = "0.1.3"
3
3
  end
data/lib/company_scope.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  require "request_store"
2
2
  #
3
+ require File.dirname(__FILE__) + '/rack/multi_company'
3
4
  require File.dirname(__FILE__) + '/company_scope/base'
4
5
  require File.dirname(__FILE__) + '/company_scope/guardian'
5
6
  require File.dirname(__FILE__) + '/company_scope/control'
@@ -0,0 +1,44 @@
1
+ #
2
+ module Rack
3
+ #
4
+ class MultiCompany
5
+ #
6
+ attr_reader :company_class_name
7
+ #
8
+ def initialize(app, company_class)
9
+ @app = app
10
+ @company_class_name = company_class.to_s.split('_').collect!{ |w| w.capitalize }.join
11
+ @company = Module.const_get(@company_class_name).find_by_company_name('DEFAULT') if db_configured
12
+ end
13
+
14
+ def call(env)
15
+ request = Rack::Request.new(env)
16
+ first_sub_domain = request.host.split('.').first
17
+ # disallow any non alphabetic chars!
18
+ domain = first_sub_domain.upcase if first_sub_domain.match(/\A[a-zA-Z0-9]*\z/)
19
+ # insert the company into ENV - for the controller helper_method 'current_company'
20
+ env["COMPANY_ID"] = retrieve_company_from_subdomain(domain)
21
+ response = @app.call(env)
22
+ response
23
+ end
24
+
25
+ private
26
+
27
+ def db_configured
28
+ ActiveRecord::Base.connection.table_exists? Module.const_get(@company_class_name).table_name
29
+ end
30
+
31
+ def retrieve_company_from_subdomain(domain)
32
+ # - During test runs we load a company called 'DEFAULT' - it does not need to exist during initialisation
33
+ @company = Module.const_get(@company_class_name).find_by_company_name('DEFAULT') if Rails.env == 'test'
34
+
35
+ # - only ever load the company when the subdomain changes - also works when company is nil from an unsuccessful attempt..
36
+ @company = Module.const_get(@company_class_name).find_by_company_name(domain) unless ( domain == @company.to_s )
37
+
38
+ @company
39
+ rescue ActiveRecord::RecordNotFound => e
40
+ puts "\n\n Rack Error - Company not found: #{e.to_s}\n\n"
41
+ nil
42
+ end
43
+ end
44
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: company_scope
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.1.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Steve Forkin
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2015-03-19 00:00:00.000000000 Z
11
+ date: 2015-03-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -38,6 +38,20 @@ dependencies:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
40
  version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rack
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'
41
55
  - !ruby/object:Gem::Dependency
42
56
  name: rspec
43
57
  requirement: !ruby/object:Gem::Requirement
@@ -176,6 +190,7 @@ files:
176
190
  - lib/company_scope/guardian.rb
177
191
  - lib/company_scope/railtie.rb
178
192
  - lib/company_scope/version.rb
193
+ - lib/rack/multi_company.rb
179
194
  homepage: http://github.com/netflakes/company_scope
180
195
  licenses: []
181
196
  metadata: {}