comable-apartment 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (86) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +19 -0
  3. data/.travis.yml +22 -0
  4. data/CHANGELOG.md +3 -0
  5. data/Gemfile +4 -0
  6. data/MIT-LICENSE +22 -0
  7. data/README.md +56 -0
  8. data/Rakefile +19 -0
  9. data/app/assets/javascripts/comable/apartment/application.coffee +14 -0
  10. data/app/assets/javascripts/comable/apartment/dispatcher.coffee +0 -0
  11. data/app/assets/stylesheets/comable/apartment/application.scss +10 -0
  12. data/app/controllers/comable/apartment/application_controller.rb +57 -0
  13. data/app/controllers/comable/apartment/dashboard_controller.rb +10 -0
  14. data/app/controllers/comable/apartment/tenants_controller.rb +55 -0
  15. data/app/controllers/comable/apartment/user_sessions_controller.rb +8 -0
  16. data/app/controllers/comable/apartment/users_controller.rb +67 -0
  17. data/app/decorators/comable/ability_decorator.rb +17 -0
  18. data/app/decorators/comable/user_decorator.rb +8 -0
  19. data/app/helpers/comable/apartment/application_helper.rb +19 -0
  20. data/app/models/comable/tenant.rb +59 -0
  21. data/app/navigations/comable/apartment/application.rb +34 -0
  22. data/app/views/comable/apartment/dashboard/show.slim +8 -0
  23. data/app/views/comable/apartment/tenants/_form.slim +19 -0
  24. data/app/views/comable/apartment/tenants/edit.slim +27 -0
  25. data/app/views/comable/apartment/tenants/index.slim +54 -0
  26. data/app/views/comable/apartment/tenants/new.slim +16 -0
  27. data/app/views/comable/apartment/user_sessions/new.slim +25 -0
  28. data/app/views/comable/apartment/users/_form.slim +24 -0
  29. data/app/views/comable/apartment/users/edit.slim +34 -0
  30. data/app/views/comable/apartment/users/index.slim +34 -0
  31. data/app/views/comable/apartment/users/new.slim +21 -0
  32. data/app/views/comable/apartment/users/show.slim +33 -0
  33. data/app/views/layouts/comable/apartment/application.slim +17 -0
  34. data/comable-apartment.gemspec +46 -0
  35. data/config/initializers/comable-apartment.rb +4 -0
  36. data/config/initializers/devise.rb +3 -0
  37. data/config/locales/en.yml +27 -0
  38. data/config/locales/ja.yml +27 -0
  39. data/config/routes.rb +14 -0
  40. data/db/migrate/20150729091221_create_comable_tenant.rb +9 -0
  41. data/db/seeds.rb +5 -0
  42. data/db/seeds/comable/users.rb +51 -0
  43. data/gemfiles/active_record_40.gemfile +4 -0
  44. data/gemfiles/active_record_41.gemfile +4 -0
  45. data/gemfiles/active_record_42.gemfile +4 -0
  46. data/gemfiles/active_record_edge.gemfile +8 -0
  47. data/gemfiles/common.gemfile +2 -0
  48. data/lib/comable/apartment.rb +62 -0
  49. data/lib/comable/apartment/constraint.rb +19 -0
  50. data/lib/comable/apartment/engine.rb +13 -0
  51. data/lib/comable/apartment/tasks/release.rake +50 -0
  52. data/lib/comable/apartment/version.rb +5 -0
  53. data/test/controllers/comable/apartment/tenants_controller_test.rb +71 -0
  54. data/test/controllers/comable/apartment/users_controller_test.rb +80 -0
  55. data/test/dummy/Rakefile +2 -0
  56. data/test/dummy/bin/rails +3 -0
  57. data/test/dummy/config.ru +2 -0
  58. data/test/dummy/config/application.rb +53 -0
  59. data/test/dummy/config/database.yml +18 -0
  60. data/test/dummy/db/.gitkeep +0 -0
  61. data/test/dummy/db/migrate/20150814140744_create_comable_products.comable.rb +16 -0
  62. data/test/dummy/db/migrate/20150814140745_create_comable_users.comable.rb +47 -0
  63. data/test/dummy/db/migrate/20150814140746_create_comable_stocks.comable.rb +15 -0
  64. data/test/dummy/db/migrate/20150814140747_create_comable_orders.comable.rb +21 -0
  65. data/test/dummy/db/migrate/20150814140748_create_comable_order_items.comable.rb +20 -0
  66. data/test/dummy/db/migrate/20150814140749_create_comable_payment_methods.comable.rb +14 -0
  67. data/test/dummy/db/migrate/20150814140750_create_comable_shipment_methods.comable.rb +12 -0
  68. data/test/dummy/db/migrate/20150814140751_create_comable_stores.comable.rb +12 -0
  69. data/test/dummy/db/migrate/20150814140752_create_comable_addresses.comable.rb +18 -0
  70. data/test/dummy/db/migrate/20150814140753_create_comable_categories.comable.rb +11 -0
  71. data/test/dummy/db/migrate/20150814140754_create_comable_products_categories.comable.rb +9 -0
  72. data/test/dummy/db/migrate/20150814140755_create_comable_images.comable.rb +10 -0
  73. data/test/dummy/db/migrate/20150814140756_create_comable_shipments.comable.rb +14 -0
  74. data/test/dummy/db/migrate/20150814140757_create_comable_payments.comable.rb +13 -0
  75. data/test/dummy/db/migrate/20150814140758_create_comable_trackers.comable.rb +13 -0
  76. data/test/dummy/db/migrate/20150814140759_create_comable_pages.comable.rb +18 -0
  77. data/test/dummy/db/migrate/20150814140760_create_comable_themes.comable.rb +16 -0
  78. data/test/dummy/db/migrate/20150814140761_add_theme_id_to_comable_stores.comable.rb +8 -0
  79. data/test/factories/comable/tenants.rb +6 -0
  80. data/test/factories/comable/users.rb +6 -0
  81. data/test/lib/comable/apartment/version_test.rb +7 -0
  82. data/test/lib/comable/apartment_test.rb +27 -0
  83. data/test/minitest_helper.rb +29 -0
  84. data/test/models/comable/tenant_test.rb +81 -0
  85. data/test/support/have_attributes.rb +36 -0
  86. metadata +529 -0
@@ -0,0 +1,59 @@
1
+ module Comable
2
+ class Tenant < ActiveRecord::Base
3
+ extend FriendlyId
4
+
5
+ validates :name, uniqueness: true, presence: true, length: { maximum: 255 }, exclusion: { in: %w( www ) }
6
+ validates :domain, length: { maximum: 255 }
7
+
8
+ after_create :create, unless: -> { Rails.env.test? }
9
+ before_destroy :drop, unless: -> { Rails.env.test? }
10
+
11
+ # TODO: Associate a new store when create a tenant.
12
+ belongs_to :store
13
+
14
+ friendly_id :name
15
+
16
+ class << self
17
+ # @params request [ActionDispatch::Request] an instance of ActionDispatch::Request
18
+ # @return [Tenant] The tenant instance to switch
19
+ def from_request(request)
20
+ tenant = find_by(domain: request.domain) if request.domain.present?
21
+ tenant ||= find_by(name: request.subdomains.first)
22
+ tenant ||= new
23
+ tenant
24
+ end
25
+ end
26
+
27
+ def name=(name)
28
+ super name.try(:parameterize)
29
+ end
30
+
31
+ def display_name
32
+ store.try(:name) || name
33
+ end
34
+
35
+ def create
36
+ ::Apartment::Tenant.create(name)
37
+ end
38
+
39
+ def drop
40
+ ::Apartment::Tenant.drop(name)
41
+ end
42
+
43
+ def switch
44
+ ::Apartment::Tenant.switch(name) { yield }
45
+ end
46
+
47
+ def switch!
48
+ if name
49
+ ::Apartment::Tenant.switch!(name)
50
+ else
51
+ reset!
52
+ end
53
+ end
54
+
55
+ def reset!
56
+ ::Apartment::Tenant.switch!
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,34 @@
1
+ AwesomeAdminLayout.setup(only: Comable::Apartment::ApplicationController) do |controller|
2
+ comable_apartment = controller.comable_apartment
3
+ current_comable_user = controller.current_comable_user
4
+
5
+ navigation :apartment do
6
+ brand Comable.app_name
7
+
8
+ item Comable.t('apartment.dashboard') do
9
+ link comable_apartment.root_path
10
+ icon 'dashboard'
11
+ end
12
+
13
+ item Comable.t('apartment.tenants') do
14
+ link comable_apartment.tenants_path
15
+ icon 'building'
16
+ active controller.controller_name.in? %w( tenants users )
17
+ end
18
+
19
+ flex_divider
20
+
21
+ item current_comable_user.email do
22
+ nest :profile
23
+ icon 'gift'
24
+ end
25
+ end
26
+
27
+ navigation :profile do
28
+ brand current_comable_user.email
29
+
30
+ item Comable::Apartment.t(:sign_out) do
31
+ link comable_apartment.destroy_root_user_session_path, method: :delete
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,8 @@
1
+ .comable-page
2
+ .comable-page-heading
3
+ h1.page-header
4
+ = Comable.t('apartment.dashboard')
5
+
6
+ .comable-page-body
7
+ section
8
+ | Test
@@ -0,0 +1,19 @@
1
+ = error_messages_for @tenant
2
+
3
+ = form_for [comable_apartment, @tenant] do |f|
4
+ .hidden
5
+ = f.submit
6
+
7
+ fieldset
8
+ .col-md-3
9
+ legend
10
+ = Comable::Apartment.t(:general)
11
+
12
+ .col-md-9
13
+ .form-group
14
+ = f.label :name
15
+ = f.text_field :name, disabled: @tenant.persisted?
16
+
17
+ .form-group
18
+ = f.label :domain
19
+ = f.text_field :domain
@@ -0,0 +1,27 @@
1
+ .comable-page
2
+ .comable-main-fixed-top
3
+ .comable-page-heading
4
+ ul.pull-right.list-inline
5
+ li
6
+ = link_to_save
7
+
8
+ h1.page-header
9
+ ol.breadcrumb
10
+ li>
11
+ = link_to Comable::Apartment.t(:tenants), comable_apartment.tenants_path
12
+ li.active
13
+ = @tenant.name
14
+
15
+ .comable-page-body
16
+ = render 'form'
17
+ hr
18
+ .panel.panel-danger
19
+ .panel-heading type="button" data-toggle="collapse" data-target="#comable-danger"
20
+ strong
21
+ span.fa.fa-angle-down>
22
+ = Comable::Apartment.t(:destroy)
23
+ #comable-danger.collapse
24
+ .panel-body
25
+ p
26
+ = Comable::Apartment.t(:confirmation_before_destroy)
27
+ = link_to Comable::Apartment.t(:destroy), comable_apartment.tenant_path(@tenant), method: :delete, class: 'btn btn-danger'
@@ -0,0 +1,54 @@
1
+ .comable-page
2
+ .comable-page-heading
3
+ ul.pull-right.list-inline
4
+ li
5
+ = link_to Comable::Apartment.t(:new), comable_apartment.new_tenant_path, class: 'btn btn-default'
6
+
7
+ h1.page-header
8
+ = Comable::Apartment.t(:tenants)
9
+ small<
10
+ | #{@tenants.size} #{Comable::Apartment.t(:results)}
11
+
12
+ .comable-page-body
13
+ - if @tenants.empty?
14
+ = Comable::Apartment.t(:not_found)
15
+ - else
16
+ fieldset
17
+ .row
18
+ .col-md-3
19
+ legend
20
+ = Comable::Apartment.t(:manage_tenants)
21
+ .help-block
22
+ = Comable::Apartment.t(:you_can_manage_tenants_form_this_page)
23
+
24
+ .col-md-9
25
+ .row
26
+ - @tenants.each do |tenant|
27
+ .col-sm-6
28
+ .panel.panel-default
29
+ .panel-heading
30
+ .pull-right
31
+ = link_to comable_apartment.tenant_path(tenant), class: 'btn btn-default' do
32
+ i.fa.fa-edit>
33
+ = Comable::Apartment.t(:edit)
34
+ h4
35
+ = tenant.display_name
36
+ small<
37
+ = tenant.domain
38
+ .panel-body
39
+ - store_url_options = store_url_options(tenant)
40
+ ul.nav.nav-pills.nav-stacked
41
+ - if comable.respond_to? :root_url
42
+ li
43
+ = link_to Comable::Apartment.t(:visit_store), comable.root_url(store_url_options)
44
+ - else
45
+ li
46
+ = link_to Comable::Apartment.t(:visit_store), root_url(store_url_options)
47
+ - if comable.respond_to? :admin_root_url
48
+ li
49
+ = link_to Comable::Apartment.t(:visit_admin), comable.admin_root_url(store_url_options)
50
+ li
51
+ = link_to comable_apartment.tenant_users_path(tenant) do
52
+ = Comable::Apartment.t(:users)
53
+ span.badge<
54
+ = tenant.switch { Comable::User.with_role(*admin_roles).count }
@@ -0,0 +1,16 @@
1
+ .comable-page
2
+ .comable-main-fixed-top
3
+ .comable-page-heading
4
+ ul.pull-right.list-inline
5
+ li
6
+ = link_to_save
7
+
8
+ h1.page-header
9
+ ol.breadcrumb
10
+ li>
11
+ = link_to Comable::Apartment.t(:tenants), comable_apartment.tenants_path
12
+ li.active
13
+ = Comable::Apartment.t(:new)
14
+
15
+ .comable-page-body
16
+ = render 'form'
@@ -0,0 +1,25 @@
1
+ - content_for :head do
2
+ link href="//fonts.googleapis.com/css?family=Open+Sans:300,400,600,700" rel="stylesheet"
3
+
4
+ .comable-signin
5
+ .comable-signin-heading
6
+ h1.page-header
7
+ = Comable.app_name
8
+ small
9
+ = Comable::Apartment.t(:comable_apartment_provides_multi_tenancy)
10
+
11
+ .comable-signin-body
12
+ = form_for resource, as: resource_name, url: comable_apartment.root_user_session_path do |f|
13
+ .form-group
14
+ = f.email_field :email, placeholder: f.object.class.human_attribute_name(:email)
15
+
16
+ .form-group
17
+ = f.password_field :password, placeholder: f.object.class.human_attribute_name(:password)
18
+
19
+ .form-group
20
+ .checkbox
21
+ = f.label :remember_me do
22
+ = f.check_box :remember_me
23
+ = f.object.class.human_attribute_name(:remember_me)
24
+
25
+ = f.submit Comable::Apartment.t(:sign_in), class: 'btn btn-primary btn-block btn-lg'
@@ -0,0 +1,24 @@
1
+ = error_messages_for @user
2
+
3
+ = form_for [comable_apartment, @tenant, @user] do |f|
4
+ .hidden
5
+ = f.submit
6
+
7
+ fieldset
8
+ .col-md-3
9
+ legend
10
+ = Comable::Apartment.t(:general)
11
+ .help-block
12
+
13
+ .col-md-9
14
+ .form-group
15
+ = f.label :role
16
+ = f.select :role, @user.class.role.options(only: admin_roles)
17
+
18
+ .form-group
19
+ = f.label :email
20
+ = f.text_field :email
21
+
22
+ .form-group
23
+ = f.label :password
24
+ = f.password_field :password
@@ -0,0 +1,34 @@
1
+ .comable-page
2
+ .comable-main-fixed-top
3
+ .comable-page-heading
4
+ ul.pull-right.list-inline
5
+ li
6
+ = link_to_save
7
+
8
+ h1.page-header
9
+ ol.breadcrumb
10
+ li>
11
+ = link_to Comable::Apartment.t(:tenants), comable_apartment.tenants_path
12
+ li>
13
+ = link_to @tenant.name, comable_apartment.tenant_path(@tenant)
14
+ li
15
+ = link_to Comable::Apartment.t(:users), comable_apartment.tenant_users_path(@tenant)
16
+ li.active
17
+ = @user.human_id
18
+ - if @user.bill_full_name
19
+ small<
20
+ = Comable.t('honorific', name: @user.bill_full_name)
21
+
22
+ .comable-page-body
23
+ = render 'form'
24
+ hr
25
+ .panel.panel-danger
26
+ .panel-heading type="button" data-toggle="collapse" data-target="#comable-danger"
27
+ strong
28
+ span.fa.fa-angle-down>
29
+ = Comable::Apartment.t(:destroy)
30
+ #comable-danger.collapse
31
+ .panel-body
32
+ p
33
+ = Comable::Apartment.t(:confirmation_before_destroy)
34
+ = link_to Comable::Apartment.t(:destroy), comable_apartment.tenant_user_path(@tenant, @user), method: :delete, class: 'btn btn-danger'
@@ -0,0 +1,34 @@
1
+ .comable-page
2
+ .comable-page-heading
3
+ ul.pull-right.list-inline
4
+ li
5
+ = link_to Comable::Apartment.t(:new), comable_apartment.new_tenant_user_path(@tenant), class: 'btn btn-default'
6
+
7
+ h1.page-header
8
+ ol.breadcrumb
9
+ li>
10
+ = link_to Comable::Apartment.t(:tenants), comable_apartment.tenants_path
11
+ li>
12
+ = link_to @tenant.name, comable_apartment.tenant_path(@tenant)
13
+ li.active
14
+ = Comable::Apartment.t(:users)
15
+ small<
16
+ | #{@users.size} #{Comable::Apartment.t(:results)}
17
+
18
+ section
19
+ - if @users.empty?
20
+ = Comable::Apartment.t(:not_found)
21
+ - else
22
+ table.table.table-striped
23
+ thead
24
+ th
25
+ = @users.klass.human_attribute_name(:id)
26
+ th
27
+ = @users.klass.human_attribute_name(:email)
28
+ tbody
29
+ - @users.each do |user|
30
+ tr
31
+ td
32
+ = link_to user.human_id, comable_apartment.tenant_user_path(@tenant, user)
33
+ td
34
+ = user.email
@@ -0,0 +1,21 @@
1
+ .comable-page
2
+ .comable-main-fixed-top
3
+ .comable-page-heading
4
+ ul.pull-right.list-inline
5
+ li
6
+ = link_to_save
7
+
8
+ h1.page-header
9
+ ol.breadcrumb
10
+ li>
11
+ = link_to Comable::Apartment.t(:tenants), comable_apartment.tenants_path
12
+ li>
13
+ = link_to @tenant.name, comable_apartment.tenant_path(@tenant)
14
+ li
15
+ = link_to Comable::Apartment.t(:users), comable_apartment.tenant_users_path(@tenant)
16
+ li.active
17
+ = Comable::Apartment.t(:new)
18
+
19
+ .comable-page-body
20
+ section
21
+ = render 'form'
@@ -0,0 +1,33 @@
1
+ .comable-page
2
+ .comable-page-heading
3
+ ul.pull-right.list-inline
4
+ li
5
+ = link_to comable.edit_admin_user_path(@user), class: 'btn btn-default' do
6
+ span.fa.fa-edit>
7
+ = Comable.t('admin.actions.edit')
8
+
9
+ h1.page-header
10
+ ol.breadcrumb
11
+ li>
12
+ = link_to Comable::Apartment.t(:tenants), comable_apartment.tenants_path
13
+ li>
14
+ = link_to @tenant.name, comable_apartment.tenant_path(@tenant)
15
+ li
16
+ = link_to Comable::Apartment.t(:users), comable_apartment.tenant_users_path(@tenant)
17
+ li.active
18
+ = @user.human_id
19
+ - if @user.bill_full_name
20
+ small<
21
+ = Comable.t('honorific', name: @user.bill_full_name)
22
+
23
+ .comable-page-body
24
+ section
25
+ dl.dl-horizontal
26
+ dt
27
+ = @user.class.human_attribute_name(:role)
28
+ dd
29
+ = @user.role.text
30
+ dt
31
+ = @user.class.human_attribute_name(:email)
32
+ dd
33
+ = @user.email
@@ -0,0 +1,17 @@
1
+ doctype html
2
+ html
3
+ head
4
+ meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" name="viewport"
5
+ title
6
+ = Comable.app_name
7
+ = stylesheet_link_tag 'comable/apartment/application', media: 'all', 'data-turbolinks-track' => true
8
+ = javascript_include_tag 'comable/apartment/application', 'data-turbolinks-track' => true
9
+ = yield :head
10
+ = csrf_meta_tags
11
+
12
+ body
13
+ - if current_comable_user.root?
14
+ = render_admin_layout :apartment do
15
+ = yield
16
+ - else
17
+ = yield
@@ -0,0 +1,46 @@
1
+ lib = File.expand_path('../lib', __FILE__)
2
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
+ require 'comable/apartment/version'
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = 'comable-apartment'
7
+ spec.version = Comable::Apartment::VERSION
8
+ spec.authors = ['YOSHIDA Hiroki']
9
+ spec.email = ['hyoshida@appirits.com']
10
+ spec.summary = 'Multi-tenancy with Comable'
11
+ spec.description = 'Multi-tenancy with Comable using the Apartment gem'
12
+ spec.homepage = 'https://github.com/appirits/comable-apartment'
13
+ spec.license = 'MIT'
14
+
15
+ spec.files = `git ls-files -z`.split("\x0")
16
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
17
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
18
+ spec.require_paths = ['lib']
19
+
20
+ spec.add_dependency 'apartment', '~> 1.0'
21
+ spec.add_dependency 'comable-core', '~> 0.6'
22
+ spec.add_dependency 'slim-rails', '~> 3.0'
23
+ spec.add_dependency 'coffee-rails', '>= 3.2.2', '< 4.2'
24
+ spec.add_dependency 'compass-rails', '~> 2.0', '>= 2.0.4'
25
+ spec.add_dependency 'uglifier', '~> 2.7'
26
+ spec.add_dependency 'bootstrap-sass', '~> 3.3'
27
+ spec.add_dependency 'font-awesome-rails', '~> 4.3'
28
+ spec.add_dependency 'dynamic_form', '~> 1.1'
29
+ spec.add_dependency 'jquery-rails', '>= 3.1.2', '< 4.1'
30
+ spec.add_dependency 'jquery-ui-rails', '~> 5.0'
31
+ spec.add_dependency 'raphael-rails', '~> 2.1'
32
+ spec.add_dependency 'morrisjs-rails', '~> 0.5'
33
+ spec.add_dependency 'nprogress-rails', '~> 0.1.6'
34
+ spec.add_dependency 'turbolinks', '~> 2.5'
35
+ spec.add_dependency 'jquery-turbolinks', '~> 2.1'
36
+ spec.add_dependency 'awesome_admin_layout', '~> 0.2'
37
+
38
+ spec.add_development_dependency 'bundler', '~> 1.7'
39
+ spec.add_development_dependency 'rake', '~> 10.0'
40
+ spec.add_development_dependency 'minitest'
41
+ spec.add_development_dependency 'minitest-reporters'
42
+ spec.add_development_dependency 'minitest-matchers'
43
+ spec.add_development_dependency 'shoulda'
44
+ spec.add_development_dependency 'factory_girl_rails'
45
+ spec.add_development_dependency 'pg'
46
+ end