Skip to content

Commit

Permalink
Update to Spree v3 and v4
Browse files Browse the repository at this point in the history
  • Loading branch information
earllevine committed Mar 5, 2020
1 parent 234a17d commit 25a850f
Show file tree
Hide file tree
Showing 27 changed files with 542 additions and 195 deletions.
5 changes: 3 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
language: ruby
rvm:
- 2.0.0
- 2.5.3
services:
- xvfb
before_script:
- "export DISPLAY=:99.0"
- "sh -e /etc/init.d/xvfb start"
- 'bundle exec rake test_app'
script: 'bundle exec rspec spec'
19 changes: 15 additions & 4 deletions Gemfile
Original file line number Diff line number Diff line change
@@ -1,9 +1,20 @@
source 'http://rubygems.org'
source 'https://rubygems.org'

group :assets do
gem 'therubyracer'
git_source(:github) do |repo_name|
repo_name = "#{repo_name}/#{repo_name}" unless repo_name.include?('/')
"https://github.com/#{repo_name}.git"
end

gem 'spree_auth_devise', github: 'spree/spree_auth_devise', branch: '2-2-stable'
gem 'spree_core', github: 'spree/spree', branch: 'master'
gem 'spree_backend', github: 'spree/spree', branch: 'master'
gem 'spree_frontend', github: 'spree/spree', branch: 'master'
# Provides basic authentication functionality for testing parts of your engine
gem 'spree_auth_devise', github: 'spree/spree_auth_devise', branch: 'master'
gem 'rails-controller-testing'

gem 'sqlite3', '~> 1.4'

gem 'rubocop', require: false
gem 'rubocop-rspec', require: false

gemspec
32 changes: 27 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,24 @@ Adds multi-tenant support to Spree. Allows completely separate Spree sites with
Install
=======

Disable caching in `config/application.rb` (and check `config/environments/*`):

```ruby
config.cache_store = :memory_store, {size: 0}
```

Set ActiveJob's queue adapter to a persistent implementation such as `:delayed_job` or `:sidekiq`. Do not use `:async` or `:inline`.

```ruby
config.active_job.queue_adapter = :delayed_job
```

Gemfile:

```ruby
gem 'spree', github: 'spree/spree', branch: '2-2-stable'
gem 'spree_auth_devise', github: 'spree/spree_auth_devise', branch: '2-2-stable'
gem 'spree_multi_tenant', github: 'stefansenk/spree_multi_tenant', branch: '2-2-stable'
gem 'spree'
gem 'spree_auth_devise'
gem 'spree_multi_tenant'
```

```shell
Expand Down Expand Up @@ -103,6 +115,18 @@ models.each do |model|
end
```

Customizing controller and mailer behavior
====================

In order to customize the default controller or mailer behavior, it might be necessary
to disable the default behavior in `config/initializers/spree_multi_tenant.rb`

```ruby
SpreeMultiTenant.configure do |config|
config.use_tenanted_controllers = false
config.use_tenanted_mailers = false
end
```

In a Raketask
=============
Expand Down Expand Up @@ -131,9 +155,7 @@ TODO
====

- Don't require spree_auth_devise as a depandancy.
- Allow same user email address to be used on multiple sites.
- Allow tenant specific Deface overrides.
- Allow same parmalinks to be used on multiple sites.
- Example CSS and JS files.
- Should CSS and JS files be grouped under app/tenants instead of app/assets? (e.g. app/tenants/mydomain/assets/stylesheets/store.css)
- Initialise preferences.
Expand Down
8 changes: 7 additions & 1 deletion app/controllers/controllers_decorator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,11 @@ def self.init_preferences


SpreeMultiTenant.tenanted_controllers.each do |controller|
next if !SpreeMultiTenant.configuration.use_tenanted_controllers

controller.class_eval do

prepend_around_filter :tenant_scope
prepend_around_action :tenant_scope

def current_tenant
Multitenant.current_tenant
Expand All @@ -42,3 +44,7 @@ def tenant_scope

end
end

# Define ControllersDecorator. Otherwise Zeitwerk::NameError
module ControllersDecorator
end
42 changes: 42 additions & 0 deletions app/mailers/spree_multi_tenant/base_mailer_decorator.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
module SpreeMultiTenant::BaseMailerDecorator
if SpreeMultiTenant.configuration.use_tenanted_mailers
def send_action(method_name, *args)
tenant = Multitenant.current_tenant
had_current_tenant = !tenant.nil?
if !had_current_tenant && args.first # Attempt to get tenant from args.first
if self.class == Spree::OrderMailer
order = args.first.respond_to?(:id) ? args.first : Spree::Order.find(args.first)
tenant = order.try(:tenant)
elsif self.class == Spree::ReimbursementMailer
reimbursement = args.first.respond_to?(:id) ? args.first : Spree::Reimbursement.find(args.first)
tenant = reimbursement.try(:tenant)
elsif self.class == Spree::ShipmentMailer
shipment = args.first.respond_to?(:id) ? args.first : Spree::Shipment.find(args.first)
tenant = shipment.try(:tenant)
end
end

return super unless tenant

# Add tenant views path
path = "app/tenants/#{tenant.code}/views"
prepend_view_path(path)

if had_current_tenant
super
else
# Execute ActiveRecord queries within the scope of the tenant
SpreeMultiTenant.with_tenant tenant do
super
end
end
end
end
end

mailer_classes = [
Spree::BaseMailer,
]
mailer_classes.each do |mailer_class|
mailer_class.include(SpreeMultiTenant::BaseMailerDecorator)
end
19 changes: 18 additions & 1 deletion app/models/models_decorator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,21 @@ def raise_error_if_no_tenant(association = :tenant)
model.class_eval do

belongs_to :tenant
belongs_to_multitenant

# Override belongs_to_multitenant implementation in multitenant gem, because
# the default_scope implementation fails with current ActiveRecord:
# ArgumentError: nil is not an ActiveRecord::Relation
# TODO: Upstream pull request to fix this in source gem.
def self.belongs_to_multitenant_fixed(association = :tenant)
reflection = reflect_on_association association
before_validation Proc.new {|m|
m.send("#{association}=".to_sym, Multitenant.current_tenant) if Multitenant.current_tenant
}, :on => :create
default_scope lambda {
Multitenant.current_tenant ? where({reflection.foreign_key => Multitenant.current_tenant.id}) : all
}
end
belongs_to_multitenant_fixed
# raise_error_if_no_tenant if Rails.env = 'production' # TODO - would this be useful?

# always scope these models with the tenant, even if requested unscoped
Expand All @@ -42,3 +56,6 @@ def get_base_scope
end
end

# Define ModelsDecorator. Otherwise Zeitwerk::NameError
module ModelsDecorator
end
4 changes: 4 additions & 0 deletions app/models/spree/tenant.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
class Spree::Tenant < ActiveRecord::Base
SpreeMultiTenant.tenanted_models.each do |model_class|
has_many model_class.name.demodulize.pluralize.underscore.to_sym,
class_name: model_class.name
end

validates :domain, presence: true
validates :domain, uniqueness: true
Expand Down
2 changes: 1 addition & 1 deletion db/migrate/20120224001629_create_tenants.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
class CreateTenants < ActiveRecord::Migration
class CreateTenants < ActiveRecord::Migration[4.2]
def change
create_table :spree_tenants do |t|
t.string :domain
Expand Down
51 changes: 6 additions & 45 deletions db/migrate/20120224230816_add_tenant_to_models.rb
Original file line number Diff line number Diff line change
@@ -1,52 +1,13 @@
class AddTenantToModels < ActiveRecord::Migration
class AddTenantToModels < ActiveRecord::Migration[4.2]
def change
tables = [
"spree_addresses",
"spree_adjustments",
"spree_assets",
"spree_calculators",
"spree_configurations",
"spree_countries",
"spree_credit_cards",
"spree_payment_methods",
"spree_inventory_units",
"spree_line_items",
"spree_log_entries",
"spree_option_types",
"spree_option_values",
"spree_orders",
"spree_payments",
"spree_preferences",
"spree_product_option_types",
"spree_product_properties",
"spree_products",
"spree_promotion_action_line_items",
"spree_promotion_actions",
"spree_promotion_rules",
"spree_properties",
"spree_prototypes",
"spree_return_authorizations",
"spree_roles",
"spree_shipments",
"spree_shipping_categories",
"spree_shipping_methods",
"spree_state_changes",
"spree_states",
"spree_tax_categories",
"spree_tax_rates",
"spree_taxonomies",
"spree_taxons",
"spree_tokenized_permissions",
"spree_trackers",
"spree_users",
"spree_variants",
"spree_zone_members",
"spree_zones",
]
tables = SpreeMultiTenant.tenanted_models.map(&:table_name).uniq
tables.each do |table|
add_column table, :tenant_id, :integer
add_column table, :tenant_id, :integer, default: 0
change_column table, :tenant_id, :integer, null: false
change_column_default table, :tenant_id, nil
add_index table, :tenant_id
end
SpreeMultiTenant.tenanted_models.each(&:reset_column_information)
end
end

This file was deleted.

15 changes: 0 additions & 15 deletions db/migrate/20140311183035_add_tennt_to_models_1.rb

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
class UpdateUniqueConstraintsForMultitenantOnSpreeTables < ActiveRecord::Migration[4.2]
def change
tables = {
country: [{name: [:case_insensitive]}, {iso_name: [:case_insensitive]}, :iso, :iso3],
customer_return: [:number],
order: [:number],
payment: [:number],
preferences: [:key],
product: [:slug],
promotion: [{code: [:case_insensitive]}],
refund_reason: [{name: [:case_insensitive]}],
reimbursement: [:number],
reimbursement_type: [{name: [:case_insensitive]}],
return_authorization: [:number],
return_authorization_reason: [{name: [:case_insensitive]}],
role: [{name: [:case_insensitive]}],
shipment: [:number],
stock_transfer: [:number],
store: [{code: [:case_insensitive]}],
tag: [:name],
user: [:email],
}

tables.each do |table, column_infos|
table_class = "Spree::#{table.to_s.classify}".safe_constantize
if table_class
table_name = table_class.table_name

column_infos.each do |column_info|
column = column_info.is_a?(Symbol) ? column_info : column_info.keys.first
column_options = column_info.is_a?(Symbol) ? [] : column_info.values.first
is_case_insensitive = column_options.include?(:case_insensitive) &&
supports_expression_index?
column_expression = is_case_insensitive ? "lower(#{column})" : column
column_expression_for_index = is_case_insensitive ? "lower_#{column}" : column
# When attempting to find the old index, might need to find by index_custom_name:
index_custom_name =
if table == :user # Special case
'email_idx_unique'
else # General case
"index_#{table_name}_on_#{column_expression_for_index}"
end

if index_exists?(table_name, column, unique: true)
remove_index table_name, column
add_index table_name, column # change to NOT unique
elsif index_name_exists?(table_name, index_custom_name)
remove_index table_name, name: index_custom_name
add_index table_name, column_expression # change to NOT unique
end

add_index table_name,
"#{column_expression}, tenant_id",
unique: true,
name: index_custom_name + "_tenant" # Avoid "Index name is too long"
end
end
end
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ def add_javascripts
def add_stylesheets
inject_into_file 'vendor/assets/stylesheets/spree/frontend/all.css', " *= require spree/frontend/spree_multi_tenant\n", :before => /\*\//, :verbose => true
inject_into_file 'vendor/assets/stylesheets/spree/backend/all.css', " *= require spree/backend/spree_multi_tenant\n", :before => /\*\//, :verbose => true

# Disable caching.
# TODO Do this in a better place.
prepend_file 'config/environments/test.rb', "Dummy::Application.configure{ config.cache_store = :memory_store, {size: 0} } \# Disable caching for spree_multi_tenant\n"
end

def add_migrations
Expand Down
Loading

0 comments on commit 25a850f

Please sign in to comment.