milia 0.3.2 → 0.3.7

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.
Files changed (42) hide show
  1. data/Gemfile +0 -1
  2. data/Gemfile.lock +7 -9
  3. data/README.rdoc +18 -7
  4. data/VERSION +1 -1
  5. data/lib/milia/base.rb +24 -0
  6. data/lib/milia/control.rb +10 -3
  7. data/milia.gemspec +22 -7
  8. data/test/rails_app/Gemfile +4 -0
  9. data/test/rails_app/Gemfile.lock +25 -12
  10. data/test/rails_app/app/controllers/application_controller.rb +15 -0
  11. data/test/rails_app/app/models/author.rb +9 -0
  12. data/test/rails_app/app/models/calendar.rb +6 -0
  13. data/test/rails_app/app/models/post.rb +15 -0
  14. data/test/rails_app/app/models/team.rb +8 -0
  15. data/test/rails_app/app/models/team_asset.rb +6 -0
  16. data/test/rails_app/app/models/user.rb +2 -0
  17. data/test/rails_app/app/models/zine.rb +6 -0
  18. data/test/rails_app/config/environments/development.rb +5 -0
  19. data/test/rails_app/config/environments/test.rb +17 -0
  20. data/test/rails_app/db/migrate/20111012231923_create_posts.rb +15 -0
  21. data/test/rails_app/db/migrate/20111013050558_create_calendars.rb +14 -0
  22. data/test/rails_app/db/migrate/20111013050657_create_zines.rb +12 -0
  23. data/test/rails_app/db/migrate/20111013050753_create_teams.rb +11 -0
  24. data/test/rails_app/db/migrate/20111013050837_create_team_assets.rb +14 -0
  25. data/test/rails_app/db/migrate/20111013053403_create_authors.rb +13 -0
  26. data/test/rails_app/db/schema.rb +68 -1
  27. data/test/rails_app/script/rails +0 -0
  28. data/test/rails_app/test/ctlr_test_helper.rb +8 -0
  29. data/test/rails_app/test/factories/units_factory.rb +84 -0
  30. data/test/rails_app/test/functional/home_controller_test.rb +1 -1
  31. data/test/rails_app/test/test_helper.rb +116 -8
  32. data/test/rails_app/test/unit/author_test.rb +30 -0
  33. data/test/rails_app/test/unit/calendar_test.rb +28 -0
  34. data/test/rails_app/test/unit/helpers/home_helper_test.rb +3 -0
  35. data/test/rails_app/test/unit/post_test.rb +62 -0
  36. data/test/rails_app/test/unit/team_test.rb +30 -0
  37. data/test/rails_app/test/unit/user_test.rb +23 -4
  38. data/test/rails_app/test/unit/zine_test.rb +28 -0
  39. data/test/rails_app/vendor/plugins/rails_log_stdout/init.rb +43 -0
  40. metadata +41 -34
  41. data/test/rails_app/test/fixtures/tenants.yml +0 -2
  42. data/test/rails_app/test/fixtures/users.yml +0 -11
data/Gemfile CHANGED
@@ -15,6 +15,5 @@ group :development, :test do
15
15
  gem "jeweler", "~> 1.6.4"
16
16
  gem "rcov", ">= 0"
17
17
  gem 'rdoc'
18
- gem 'test-unit'
19
18
  gem 'turn', :require => false
20
19
  end
@@ -33,7 +33,7 @@ GEM
33
33
  arel (2.2.1)
34
34
  bcrypt-ruby (3.0.1)
35
35
  builder (3.0.0)
36
- devise (1.4.8)
36
+ devise (1.4.9)
37
37
  bcrypt-ruby (~> 3.0)
38
38
  orm_adapter (~> 0.0.3)
39
39
  warden (~> 1.0.3)
@@ -50,12 +50,12 @@ GEM
50
50
  i18n (>= 0.4.0)
51
51
  mime-types (~> 1.16)
52
52
  treetop (~> 1.4.8)
53
- mime-types (1.16)
53
+ mime-types (1.17.2)
54
54
  multi_json (1.0.3)
55
55
  orm_adapter (0.0.5)
56
56
  pg (0.11.0)
57
- polyglot (0.3.2)
58
- rack (1.3.4)
57
+ polyglot (0.3.3)
58
+ rack (1.3.5)
59
59
  rack-cache (1.1)
60
60
  rack (>= 0.4)
61
61
  rack-mount (0.8.3)
@@ -79,16 +79,15 @@ GEM
79
79
  rake (>= 0.8.7)
80
80
  rdoc (~> 3.4)
81
81
  thor (~> 0.14.6)
82
- rake (0.9.2)
82
+ rake (0.9.2.2)
83
83
  rcov (0.9.11)
84
- rdoc (3.10)
84
+ rdoc (3.11)
85
85
  json (~> 1.4)
86
86
  shoulda (2.11.3)
87
- sprockets (2.0.2)
87
+ sprockets (2.0.3)
88
88
  hike (~> 1.2)
89
89
  rack (~> 1.0)
90
90
  tilt (~> 1.1, != 1.3.0)
91
- test-unit (2.4.0)
92
91
  thor (0.14.6)
93
92
  tilt (1.3.3)
94
93
  treetop (1.4.10)
@@ -112,5 +111,4 @@ DEPENDENCIES
112
111
  rcov
113
112
  rdoc
114
113
  shoulda
115
- test-unit
116
114
  turn
@@ -52,6 +52,8 @@ Milia expects a user session, so please set one up
52
52
  * The current version of milia requires that devise use a *User* model.
53
53
 
54
54
  === Milia setup
55
+
56
+ ==== migrations
55
57
  *ALL* models require a tenanting field, whether they are to be universal or to
56
58
  be tenanted. So make sure the following is added to each migration
57
59
 
@@ -78,6 +80,7 @@ Also create a tenants_users join table:
78
80
  end
79
81
  end
80
82
 
83
+ ==== application controller
81
84
  add the following line AFTER the devise-required filter for authentications:
82
85
 
83
86
  <i>app/controllers/application_controller.rb</i>
@@ -90,6 +93,7 @@ catch any exceptions with the following (be sure to also add the designated meth
90
93
  rescue_from ::Milia::Control::MaxTenantExceeded, :with => :max_tenants
91
94
  rescue_from ::Milia::Control::InvalidTenantAccess, :with => :invalid_tenant
92
95
 
96
+ ==== routes
93
97
  Add the following line into the devise_for :users block
94
98
 
95
99
  <i>config/routes.rb</i>
@@ -126,7 +130,12 @@ Only designate one model in this manner.
126
130
  end # class Tenant
127
131
 
128
132
  === Designate universal models
129
- Add the following acts_as_universal to *ALL* models which are to be universal:
133
+ Add the following acts_as_universal to *ALL* models which are to be universal and
134
+ remove any superfluous
135
+
136
+ belongs_to :tenant
137
+
138
+ which the generator might have generated ( acts_as_tenant will specify that ).
130
139
 
131
140
  <i>app/models/eula.rb</i>
132
141
 
@@ -136,10 +145,13 @@ Add the following acts_as_universal to *ALL* models which are to be universal:
136
145
 
137
146
  end # class Eula
138
147
 
139
- Note that the tenant_id of a universal model will always be forced to nil.
140
-
141
148
  === Designate tenanted models
142
- Add the following acts_as_tenant to *ALL* models which are to be tenanted:
149
+ Add the following acts_as_tenant to *ALL* models which are to be tenanted and
150
+ remove any superfluous
151
+
152
+ belongs_to :tenant
153
+
154
+ which the generator might have generated ( acts_as_tenant will specify that ).
143
155
 
144
156
  <i>app/models/post.rb</i>
145
157
 
@@ -149,8 +161,6 @@ Add the following acts_as_tenant to *ALL* models which are to be tenanted:
149
161
 
150
162
  end # class Post
151
163
 
152
- Note that the tenant_id of a tenanted model must always match the current
153
- valid tenant.
154
164
 
155
165
  === Exceptions raised
156
166
 
@@ -199,7 +209,8 @@ to put:
199
209
  * Milia designates a default_scope for all models (both universal and tenanted). From Rails 3.2 onwards, the last designated default scope overrides any prior scopes.
200
210
  * Milia uses Thread.current[:tenant_id] to hold the current tenant for the existing Action request in the application.
201
211
  * SQL statements executed outside the context of ActiveRecord pose a potential danger; the current milia implementation does not extend to the DB connection level and so cannot enforce tenanting at this point.
202
-
212
+ * The tenant_id of a universal model will always be forced to nil.
213
+ * The tenant_id of a tenanted model will be set to the current_tenant of the current_user upon creation.
203
214
 
204
215
 
205
216
  == Contributing to milia
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.3.2
1
+ 0.3.7
@@ -15,6 +15,9 @@ module Milia
15
15
  # ------------------------------------------------------------------------
16
16
  def acts_as_tenant()
17
17
  attr_protected :tenant_id
18
+ belongs_to :tenant
19
+ validates_presence_of :tenant_id
20
+
18
21
  default_scope lambda { where( "#{table_name}.tenant_id = ?", Thread.current[:tenant_id] ) }
19
22
 
20
23
  # ..........................callback enforcers............................
@@ -43,6 +46,8 @@ module Milia
43
46
  # ------------------------------------------------------------------------
44
47
  def acts_as_universal()
45
48
  attr_protected :tenant_id
49
+ belongs_to :tenant
50
+
46
51
  default_scope where( "#{table_name}.tenant_id IS NULL" )
47
52
 
48
53
  # ..........................callback enforcers............................
@@ -105,6 +110,25 @@ module Milia
105
110
  end # before_destroy do
106
111
 
107
112
  end
113
+
114
+ # ------------------------------------------------------------------------
115
+ # where_restrict_tenant -- gens tenant restrictive where clause for each klass
116
+ # NOTE: subordinate join tables will not get the default scope by Rails
117
+ # theoretically, the default scope on the master table alone should be sufficient
118
+ # in restricting answers to the current_tenant alone .. HOWEVER, it doesn't feel
119
+ # right. adding an additional .where( where_restrict_tenants(klass1, klass2,...))
120
+ # for each of the subordinate models in the join seems like a nice safety issue.
121
+ # ------------------------------------------------------------------------
122
+ def where_restrict_tenant(*args)
123
+ args.map{|klass| "#{klass.table_name}.tenant_id = #{Thread.current[:tenant_id]}"}.join(" AND ")
124
+ end
125
+
126
+ # ------------------------------------------------------------------------
127
+ # ------------------------------------------------------------------------
128
+
129
+ # ------------------------------------------------------------------------
130
+ # ------------------------------------------------------------------------
131
+
108
132
  # ------------------------------------------------------------------------
109
133
  # ------------------------------------------------------------------------
110
134
 
@@ -28,13 +28,19 @@ module Milia
28
28
  # ------------------------------------------------------------------------------
29
29
  def set_current_tenant( tenant_id = nil )
30
30
  if user_signed_in?
31
+
31
32
  @_my_tenants ||= current_user.tenants # gets all possible tenants for user
32
33
 
33
- if tenant_id.nil? # no arg; find automatically from user
34
- tenant_id = @_my_tenants.first.id
35
- else # passed an arg; validate tenant_id before setup
34
+ tenant_id ||= session[:tenant_id] # use session tenant_id ?
35
+
36
+ if tenant_id.nil? # no arg; find automatically based on user
37
+ tenant_id = @_my_tenants.first.id # just pick the first one
38
+ else # validate the specified tenant_id before setup
36
39
  raise InvalidTenantAccess unless @_my_tenants.any?{|tu| tu.id == tenant_id}
37
40
  end
41
+
42
+ session[:tenant_id] = tenant_id # remember it going forward
43
+
38
44
  else # user not signed in yet...
39
45
  tenant_id = 0 if tenant_id.nil? # an impossible tenant_id
40
46
  end
@@ -46,6 +52,7 @@ module Milia
46
52
 
47
53
  # ------------------------------------------------------------------------------
48
54
  # initiate_tenant -- initiates first-time tenant; establishes thread
55
+ # assumes not in a session yet (since here only upon new account sign-up)
49
56
  # ONLY for brand-new tenants upon User account sign up
50
57
  # arg
51
58
  # tenant -- tenant obj of the new tenant
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "milia"
8
- s.version = "0.3.2"
8
+ s.version = "0.3.7"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["David Anderson"]
12
- s.date = "2011-10-12"
12
+ s.date = "2011-11-05"
13
13
  s.description = "Transparent Multi-tenanting for hosted Rails 3.1+/Ruby 1.9.2 applications"
14
14
  s.email = "dsaronin@gmail.com"
15
15
  s.extra_rdoc_files = [
@@ -52,8 +52,14 @@ Gem::Specification.new do |s|
52
52
  "test/rails_app/app/helpers/home_helper.rb",
53
53
  "test/rails_app/app/mailers/.gitkeep",
54
54
  "test/rails_app/app/models/.gitkeep",
55
+ "test/rails_app/app/models/author.rb",
56
+ "test/rails_app/app/models/calendar.rb",
57
+ "test/rails_app/app/models/post.rb",
58
+ "test/rails_app/app/models/team.rb",
59
+ "test/rails_app/app/models/team_asset.rb",
55
60
  "test/rails_app/app/models/tenant.rb",
56
61
  "test/rails_app/app/models/user.rb",
62
+ "test/rails_app/app/models/zine.rb",
57
63
  "test/rails_app/app/views/home/index.html.erb",
58
64
  "test/rails_app/app/views/layouts/application.html.erb",
59
65
  "test/rails_app/config.ru",
@@ -78,6 +84,12 @@ Gem::Specification.new do |s|
78
84
  "test/rails_app/db/migrate/20111012050532_create_tenants.rb",
79
85
  "test/rails_app/db/migrate/20111012050600_create_tenants_users.rb",
80
86
  "test/rails_app/db/migrate/20111012060818_add_sessions_table.rb",
87
+ "test/rails_app/db/migrate/20111012231923_create_posts.rb",
88
+ "test/rails_app/db/migrate/20111013050558_create_calendars.rb",
89
+ "test/rails_app/db/migrate/20111013050657_create_zines.rb",
90
+ "test/rails_app/db/migrate/20111013050753_create_teams.rb",
91
+ "test/rails_app/db/migrate/20111013050837_create_team_assets.rb",
92
+ "test/rails_app/db/migrate/20111013053403_create_authors.rb",
81
93
  "test/rails_app/db/schema.rb",
82
94
  "test/rails_app/db/seeds.rb",
83
95
  "test/rails_app/lib/assets/.gitkeep",
@@ -88,20 +100,26 @@ Gem::Specification.new do |s|
88
100
  "test/rails_app/public/500.html",
89
101
  "test/rails_app/public/favicon.ico",
90
102
  "test/rails_app/script/rails",
103
+ "test/rails_app/test/ctlr_test_helper.rb",
104
+ "test/rails_app/test/factories/units_factory.rb",
91
105
  "test/rails_app/test/fixtures/.gitkeep",
92
- "test/rails_app/test/fixtures/tenants.yml",
93
- "test/rails_app/test/fixtures/users.yml",
94
106
  "test/rails_app/test/functional/.gitkeep",
95
107
  "test/rails_app/test/functional/home_controller_test.rb",
96
108
  "test/rails_app/test/integration/.gitkeep",
97
109
  "test/rails_app/test/performance/browsing_test.rb",
98
110
  "test/rails_app/test/test_helper.rb",
99
111
  "test/rails_app/test/unit/.gitkeep",
112
+ "test/rails_app/test/unit/author_test.rb",
113
+ "test/rails_app/test/unit/calendar_test.rb",
100
114
  "test/rails_app/test/unit/helpers/home_helper_test.rb",
115
+ "test/rails_app/test/unit/post_test.rb",
116
+ "test/rails_app/test/unit/team_test.rb",
101
117
  "test/rails_app/test/unit/tenant_test.rb",
102
118
  "test/rails_app/test/unit/user_test.rb",
119
+ "test/rails_app/test/unit/zine_test.rb",
103
120
  "test/rails_app/vendor/assets/stylesheets/.gitkeep",
104
121
  "test/rails_app/vendor/plugins/.gitkeep",
122
+ "test/rails_app/vendor/plugins/rails_log_stdout/init.rb",
105
123
  "test/test_milia.rb"
106
124
  ]
107
125
  s.homepage = "http://github.com/dsaronin/milia"
@@ -122,7 +140,6 @@ Gem::Specification.new do |s|
122
140
  s.add_development_dependency(%q<jeweler>, ["~> 1.6.4"])
123
141
  s.add_development_dependency(%q<rcov>, [">= 0"])
124
142
  s.add_development_dependency(%q<rdoc>, [">= 0"])
125
- s.add_development_dependency(%q<test-unit>, [">= 0"])
126
143
  s.add_development_dependency(%q<turn>, [">= 0"])
127
144
  else
128
145
  s.add_dependency(%q<rails>, [">= 3.1"])
@@ -133,7 +150,6 @@ Gem::Specification.new do |s|
133
150
  s.add_dependency(%q<jeweler>, ["~> 1.6.4"])
134
151
  s.add_dependency(%q<rcov>, [">= 0"])
135
152
  s.add_dependency(%q<rdoc>, [">= 0"])
136
- s.add_dependency(%q<test-unit>, [">= 0"])
137
153
  s.add_dependency(%q<turn>, [">= 0"])
138
154
  end
139
155
  else
@@ -145,7 +161,6 @@ Gem::Specification.new do |s|
145
161
  s.add_dependency(%q<jeweler>, ["~> 1.6.4"])
146
162
  s.add_dependency(%q<rcov>, [">= 0"])
147
163
  s.add_dependency(%q<rdoc>, [">= 0"])
148
- s.add_dependency(%q<test-unit>, [">= 0"])
149
164
  s.add_dependency(%q<turn>, [">= 0"])
150
165
  end
151
166
  end
@@ -18,6 +18,8 @@ group :assets do
18
18
  gem 'sass-rails', '~> 3.1.4'
19
19
  gem 'coffee-rails', '~> 3.1.1'
20
20
  gem 'uglifier', '>= 1.0.3'
21
+ gem 'execjs'
22
+ gem 'therubyracer'
21
23
  end
22
24
 
23
25
  gem 'jquery-rails'
@@ -35,6 +37,8 @@ gem 'jquery-rails'
35
37
  # gem 'ruby-debug19', :require => 'ruby-debug'
36
38
 
37
39
  group :test do
40
+ gem "factory_girl_rails", "~> 1.2"
41
+ gem "shoulda", ">= 0"
38
42
  # Pretty printed test output
39
43
  gem 'turn', :require => false
40
44
  end
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: ../../../milia
3
3
  specs:
4
- milia (0.3.2)
4
+ milia (0.3.6)
5
5
  devise (>= 1.4.8)
6
6
  rails (>= 3.1)
7
7
 
@@ -48,7 +48,7 @@ GEM
48
48
  execjs
49
49
  coffee-script-source (1.1.2)
50
50
  daemons (1.1.4)
51
- devise (1.4.8)
51
+ devise (1.4.9)
52
52
  bcrypt-ruby (~> 3.0)
53
53
  orm_adapter (~> 0.0.3)
54
54
  warden (~> 1.0.3)
@@ -56,25 +56,31 @@ GEM
56
56
  eventmachine (0.12.10)
57
57
  execjs (1.2.9)
58
58
  multi_json (~> 1.0)
59
- foreman (0.24.0)
59
+ factory_girl (2.2.0)
60
+ activesupport
61
+ factory_girl_rails (1.3.0)
62
+ factory_girl (~> 2.2.0)
63
+ railties (>= 3.0.0)
64
+ foreman (0.25.0)
60
65
  term-ansicolor (~> 1.0.5)
61
66
  thor (>= 0.13.6)
62
67
  hike (1.2.1)
63
68
  i18n (0.6.0)
64
- jquery-rails (1.0.14)
69
+ jquery-rails (1.0.16)
65
70
  railties (~> 3.0)
66
71
  thor (~> 0.14)
67
72
  json (1.6.1)
73
+ libv8 (3.3.10.2)
68
74
  mail (2.3.0)
69
75
  i18n (>= 0.4.0)
70
76
  mime-types (~> 1.16)
71
77
  treetop (~> 1.4.8)
72
- mime-types (1.16)
78
+ mime-types (1.17.2)
73
79
  multi_json (1.0.3)
74
80
  orm_adapter (0.0.5)
75
81
  pg (0.11.0)
76
- polyglot (0.3.2)
77
- rack (1.3.4)
82
+ polyglot (0.3.3)
83
+ rack (1.3.5)
78
84
  rack-cache (1.1)
79
85
  rack (>= 0.4)
80
86
  rack-mount (0.8.3)
@@ -98,8 +104,8 @@ GEM
98
104
  rake (>= 0.8.7)
99
105
  rdoc (~> 3.4)
100
106
  thor (~> 0.14.6)
101
- rake (0.9.2)
102
- rdoc (3.10)
107
+ rake (0.9.2.2)
108
+ rdoc (3.11)
103
109
  json (~> 1.4)
104
110
  sass (3.1.10)
105
111
  sass-rails (3.1.4)
@@ -108,11 +114,14 @@ GEM
108
114
  sass (>= 3.1.4)
109
115
  sprockets (~> 2.0.0)
110
116
  tilt (~> 1.3.2)
111
- sprockets (2.0.2)
117
+ shoulda (2.11.3)
118
+ sprockets (2.0.3)
112
119
  hike (~> 1.2)
113
120
  rack (~> 1.0)
114
121
  tilt (~> 1.1, != 1.3.0)
115
- term-ansicolor (1.0.6)
122
+ term-ansicolor (1.0.7)
123
+ therubyracer (0.9.8)
124
+ libv8 (~> 3.3.10)
116
125
  thin (1.2.11)
117
126
  daemons (>= 1.0.9)
118
127
  eventmachine (>= 0.12.6)
@@ -125,7 +134,7 @@ GEM
125
134
  turn (0.8.3)
126
135
  ansi
127
136
  tzinfo (0.3.30)
128
- uglifier (1.0.3)
137
+ uglifier (1.0.4)
129
138
  execjs (>= 0.3.0)
130
139
  multi_json (>= 1.0.2)
131
140
  warden (1.0.6)
@@ -137,6 +146,8 @@ PLATFORMS
137
146
  DEPENDENCIES
138
147
  coffee-rails (~> 3.1.1)
139
148
  devise (>= 1.4.8)
149
+ execjs
150
+ factory_girl_rails (~> 1.2)
140
151
  foreman
141
152
  jquery-rails
142
153
  milia!
@@ -144,6 +155,8 @@ DEPENDENCIES
144
155
  rails (= 3.1.1)
145
156
  rdoc
146
157
  sass-rails (~> 3.1.4)
158
+ shoulda
159
+ therubyracer
147
160
  thin
148
161
  turn
149
162
  uglifier (>= 1.0.3)
@@ -1,5 +1,20 @@
1
1
  class ApplicationController < ActionController::Base
2
2
  protect_from_forgery
3
+
4
+ before_filter :configure_mailer
3
5
  before_filter :authenticate_user!
4
6
  before_filter :set_current_tenant # forces milia to set up current tenant
7
+
8
+ protected
9
+
10
+ # ------------------------------------------------------------------------------
11
+ # ------------------------------------------------------------------------------
12
+ def configure_mailer
13
+ ActionMailer::Base.default_url_options[:host] = request.host
14
+ ActionMailer::Base.default_url_options[:port] = request.port unless request.port == 80
15
+ end
16
+
17
+
18
+
19
+
5
20
  end