Git Product home page Git Product logo

spree_shared's Introduction

⚠️ Deprecation notice ⚠️

Spree supports multi-store scenarios out of the box. The apartment gem, which this gem depends on is not maintained anymore, hence we won't maintain and support this gem anymore.

Spree Shared

Build Status Code Climate

Multiple stores using a single Spree application instance.

Uses request subdomain to swap database, Rails cache (preferences), image paths.


Installation

  1. Add to your Gemfile:

    gem 'spree_shared', github: 'spree-contrib/spree_shared', branch: 'master'

    Make sure your config/database.yml has valid db connection.

  2. Create config/initializers/apartment.rbwith the following command:

    bundle exec rails generate apartment:install
  3. Search for following line inside config/initializers/apartment.rb:

      config.tenant_names = lambda { ToDo_Tenant_Or_User_Model.pluck :database }

    And change it to include two sample subdomains:

      config.tenant_names = %w(store1 store2)
  4. Bootstrap sample stores:

    bundle exec rake spree_shared:bootstrap['store1']
    bundle exec rake spree_shared:bootstrap['store2']
  5. Setup local subdomains for sample stores, as spree_shared uses by default subdomain routing you need to confirm some local domains such as:

    store1.spree.dev store2.spree.dev

    This can be done using Pow or editing your local /etc/hosts file.

  6. Set namespace for cache engine in development.rb and/or production.rb

    config.cache_store = :memory_store, { namespace: -> { Apartment::Tenant.current } }

Setting Store Preferences

If you'd like to set preferences for every store you can do so in your config/initializers/spree.rb initializer by iterating over each store, and then setting it's preference. Since this is multi-tenant with each store having their own database the usual Spree.config block can't be used as it only sets the preference for a single database.

Here is an example:

require 'spree_shared/tenant_decorator'

Apartment::Tenant.each do |tenant_name| # also each_with_default available
  Spree::Config.auto_capture = true
rescue
  puts "  Failed to set up config for store '#{tenant_name}'"
end

Contributing

See corresponding guidelines


Copyright (c) 2013-2015 Spree Commerce Inc, and other contributors, released under the New BSD License

spree_shared's People

Contributors

bdq avatar damianlegawiec avatar futhr avatar gtluszcz avatar huoxito avatar jdutil avatar lbrapid avatar patrice avatar pawelnguyen avatar romul avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

spree_shared's Issues

Rake aborted

$ bundle exec rake spree_shared:bootstrap['store1']
rake aborted!
NoMethodError: undefined method 'tenant_proc=' for #Class:0x007f9b4b9142c0
/Users/PATH_OF_PROJECT/config/initializers/apartment.rb:51:in '<top (required)>'
/Users/PATH_OF_PROJECT/config/environment.rb:5:in `<top (required)>'
Tasks: TOP => spree_shared:bootstrap => environment
(See full trace by running task with --trace)

load seed not working

branch 3-0-stable
file lib/tasks/db.rake:16

the seed does not load.
The problem is not with this gem is with Spree because in 'spree_core' the task "db:load_dir" is used 'require' insted of 'load'.
'require' only load the file ones for each server start, so for a multitenant app this is a problem because seeds are only loaded in the first tenant.

So i was wondering if this issue can be solve in this gem.

regards

Not compatible with Rails 7.0

I have been trying to setup multi-tenancy with Spree 4.6 running on Rails 7. Looks like ros-apartment gem is no longer being maintained and not properly compatible with Rails 7. This, therefore, makes the spree_shared gem incompatible with Rails 7.
For now I could get it to work by downgrading rails to 6.1 in Spree.

Are there any plans to fix this or start supporting newer versions?

Issue with Sidekiq on Spree 3.0 with spree_shared

In development mode (config.cache_classes = false) bundle exec sidekiq causes the such error:

Cannot define multiple 'included' blocks for a Concern
/Users/roman/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/activesupport-4.2.0/lib/active_support/concern.rb:126:in `included'
/Users/roman/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/bundler/gems/spree-80c47e09d7bc/core/app/models/spree/preferences/preferable.rb:37:in `<module:Preferable>'
/Users/roman/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/bundler/gems/spree-80c47e09d7bc/core/app/models/spree/preferences/preferable.rb:34:in `<top (required)>'
...
/Users/roman/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/railties-4.2.0/lib/rails/initializable.rb:54:in `run_initializers'
/Users/roman/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/railties-4.2.0/lib/rails/application.rb:352:in `initialize!'
/Users/roman/www/application/config/environment.rb:5:in `<top (required)>'
/Users/roman/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/polyglot-0.3.5/lib/polyglot.rb:65:in `require'
/Users/roman/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/polyglot-0.3.5/lib/polyglot.rb:65:in `require'
/Users/roman/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/activesupport-4.2.0/lib/active_support/dependencies.rb:274:in `block in require'
/Users/roman/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/activesupport-4.2.0/lib/active_support/dependencies.rb:240:in `load_dependency'
/Users/roman/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/activesupport-4.2.0/lib/active_support/dependencies.rb:274:in `require'
/Users/roman/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/sidekiq-3.3.2/lib/sidekiq/cli.rb:236:in `boot_system'
/Users/roman/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/sidekiq-3.3.2/lib/sidekiq/cli.rb:50:in `run'
/Users/roman/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/sidekiq-3.3.2/bin/sidekiq:8:in `<top (required)>'
/Users/roman/.rbenv/versions/2.1.2/bin/sidekiq:23:in `load'
/Users/roman/.rbenv/versions/2.1.2/bin/sidekiq:23:in `<main>'

Looks like a double load of some files. I'm pretty sure, that this bug isn't restricted to sidekiq and can appear in other cases.

Cannot install spree_shared gem

Hello,
I created a new Rails 4.2.1 project and installed ruby 2.1.6p336
I added to gemfile:
gem 'spree_shared', github: 'spree-contrib/spree_shared', branch: 'master'
However, when running bundle -> install I get this error:
Bundler could not find compatible versions for gem "spree_core":

In Gemfile:
spree_shared (>= 0) ruby depends on
spree_core (> 3.1.0.beta) ruby
Could not find gem 'spree_core (
> 3.1.0.beta) ruby', which is required by gem
'spree_shared (>= 0) ruby', in any of the sources.

I tried to install spree_core, but after the errors, I guess now it is only spree, so I did:
gem install spree
And it seemed to have installed fine.

and tried bundle install again to install spree_shared, but the error persisted.
Can anyone help me?
I want to test the spree_shared and if there is some way to configure the gemfile, even if it means I need to use older version of spree, it would be fine for now.
Thank you,
Nuno

Problem customizing tenant identifier in image paths

The README states the following regarding customizing the tenant identifier:

By default tenant will resolve to Apartment::Tenant.current_tenant but you can change it - eg. suppose you use databases like tenant_12345 and only want tenant id in file path, then add following line to config/initializers/apartment.rb

Spree::Image.tenant_proc = -> { Apartment::Tenant.current_tenant.match(/(\d+)/)[1] }

However in practice I don't think this works as the tenant_proc method is not defined until the engine's activate method is called, which doesn't seem to occur until after the initializers have been run.

Preferences should not be shared between stores

Currently, preferences are shared between different stores. This is undesirable and can probably be solved by setting ENV['RAILS_CACHE_ID'] within the Spree::Shared::Switcher#call method.

Error on spree_shared:bootstrap task

Output of the task:

Loading seed & sample data into database: store2
loading ruby /home/thelinuxlich/.gem/ruby/2.1.0/gems/spree_core-2.2.0/db/default/spree/countries.rb
loading ruby /home/thelinuxlich/.gem/ruby/2.1.0/gems/spree_core-2.2.0/db/default/spree/roles.rb
loading ruby /home/thelinuxlich/.gem/ruby/2.1.0/gems/spree_core-2.2.0/db/default/spree/states.rb
loading ruby /home/thelinuxlich/.gem/ruby/2.1.0/gems/spree_core-2.2.0/db/default/spree/zones.rb
loading ruby /home/thelinuxlich/.bundler/ruby/2.1.0/spree_auth_devise-6469c80cbb8f/db/default/users.rb
Done!
Seeding store1 tenant
Seeding store2 tenant
Loaded Payment Methods samples
Loaded Shipping Categories samples
Loaded Shipping Methods samples
Loaded Tax Categories samples
Loaded Tax Rates samples
Loaded Products samples
Loaded Taxonomies samples
Loaded Taxons samples
Loaded Option Types samples
Loaded Option Values samples
Loaded Product Option Types samples
Loaded Product Properties samples
Loaded Prototypes samples
Loaded Variants samples
Loaded Stock samples
Loading images for Ruby on Rails Tote
Loading images for Ruby on Rails Bag
Loading images for Ruby on Rails Baseball Jersey
Loading images for Ruby on Rails Jr. Spaghetti
Loading images for Ruby on Rails Mug
Loading images for Ruby on Rails Ringer T-Shirt
Loading images for Ruby on Rails Stein
Loading images for Apache Baseball Jersey
Loading images for Ruby Baseball Jersey
Loading images for Spree Bag
Loading images for Spree Tote
Loading images for Spree Ringer T-Shirt
Loading images for Spree Jr. Spaghetti
Loading images for Spree Baseball Jersey
Loading images for Spree Stein
Loading images for Spree Mug
Loaded Assets samples
Loaded Addresses samples
Loaded Orders samples
Loaded Adjustments samples
Loaded Payments samples
rake aborted!
Validation failed: Credit card Name can't be blank
/home/thelinuxlich/.gem/ruby/2.1.0/gems/activerecord-4.0.3/lib/active_record/validations.rb:57:in `save!'
/home/thelinuxlich/.gem/ruby/2.1.0/gems/activerecord-4.0.3/lib/active_record/attribute_methods/dirty.rb:41:in `save!'
/home/thelinuxlich/.gem/ruby/2.1.0/gems/activerecord-4.0.3/lib/active_record/transactions.rb:275:in `block in save!'
/home/thelinuxlich/.gem/ruby/2.1.0/gems/activerecord-4.0.3/lib/active_record/transactions.rb:326:in `block in with_transaction_returning_status'
/home/thelinuxlich/.gem/ruby/2.1.0/gems/activerecord-4.0.3/lib/active_record/connection_adapters/abstract/database_statements.rb:200:in `transaction'
/home/thelinuxlich/.gem/ruby/2.1.0/gems/activerecord-4.0.3/lib/active_record/transactions.rb:209:in `transaction'
/home/thelinuxlich/.gem/ruby/2.1.0/gems/activerecord-4.0.3/lib/active_record/transactions.rb:323:in `with_transaction_returning_status'
/home/thelinuxlich/.gem/ruby/2.1.0/gems/activerecord-4.0.3/lib/active_record/transactions.rb:275:in `save!'
/home/thelinuxlich/.gem/ruby/2.1.0/gems/state_machine-1.2.0/lib/state_machine/integrations/active_record.rb:487:in `block in save!'
/home/thelinuxlich/.gem/ruby/2.1.0/gems/state_machine-1.2.0/lib/state_machine/integrations/active_record.rb:502:in `block (2 levels) in around_save'
/home/thelinuxlich/.gem/ruby/2.1.0/gems/state_machine-1.2.0/lib/state_machine/transition_collection.rb:150:in `block in run_actions'
/home/thelinuxlich/.gem/ruby/2.1.0/gems/state_machine-1.2.0/lib/state_machine/transition_collection.rb:170:in `catch_exceptions'
/home/thelinuxlich/.gem/ruby/2.1.0/gems/state_machine-1.2.0/lib/state_machine/transition_collection.rb:148:in `run_actions'
/home/thelinuxlich/.gem/ruby/2.1.0/gems/state_machine-1.2.0/lib/state_machine/transition_collection.rb:133:in `run_callbacks'
/home/thelinuxlich/.gem/ruby/2.1.0/gems/state_machine-1.2.0/lib/state_machine/transition_collection.rb:212:in `run_callbacks'
/home/thelinuxlich/.gem/ruby/2.1.0/gems/state_machine-1.2.0/lib/state_machine/transition_collection.rb:63:in `block (2 levels) in perform'
/home/thelinuxlich/.gem/ruby/2.1.0/gems/state_machine-1.2.0/lib/state_machine/transition_collection.rb:63:in `catch'
/home/thelinuxlich/.gem/ruby/2.1.0/gems/state_machine-1.2.0/lib/state_machine/transition_collection.rb:63:in `block in perform'
/home/thelinuxlich/.gem/ruby/2.1.0/gems/state_machine-1.2.0/lib/state_machine/transition_collection.rb:186:in `within_transaction'
/home/thelinuxlich/.gem/ruby/2.1.0/gems/state_machine-1.2.0/lib/state_machine/transition_collection.rb:62:in `perform'
/home/thelinuxlich/.gem/ruby/2.1.0/gems/state_machine-1.2.0/lib/state_machine/integrations/active_record.rb:502:in `block in around_save'
/home/thelinuxlich/.gem/ruby/2.1.0/gems/state_machine-1.2.0/lib/state_machine/integrations/active_record.rb:530:in `block in transaction'
/home/thelinuxlich/.gem/ruby/2.1.0/gems/activerecord-4.0.3/lib/active_record/connection_adapters/abstract/database_statements.rb:200:in `transaction'
/home/thelinuxlich/.gem/ruby/2.1.0/gems/activerecord-4.0.3/lib/active_record/transactions.rb:209:in `transaction'
/home/thelinuxlich/.gem/ruby/2.1.0/gems/state_machine-1.2.0/lib/state_machine/integrations/active_record.rb:529:in `transaction'
/home/thelinuxlich/.gem/ruby/2.1.0/gems/state_machine-1.2.0/lib/state_machine/integrations/active_record.rb:501:in `around_save'
/home/thelinuxlich/.gem/ruby/2.1.0/gems/state_machine-1.2.0/lib/state_machine/integrations/active_record.rb:487:in `save!'
/home/thelinuxlich/.gem/ruby/2.1.0/gems/activerecord-4.0.3/lib/active_record/associations/has_many_association.rb:38:in `insert_record'
/home/thelinuxlich/.gem/ruby/2.1.0/gems/activerecord-4.0.3/lib/active_record/associations/collection_association.rb:463:in `block (2 levels) in create_record'
/home/thelinuxlich/.gem/ruby/2.1.0/gems/activerecord-4.0.3/lib/active_record/associations/collection_association.rb:367:in `add_to_target'
/home/thelinuxlich/.gem/ruby/2.1.0/gems/activerecord-4.0.3/lib/active_record/associations/collection_association.rb:461:in `block in create_record'
/home/thelinuxlich/.gem/ruby/2.1.0/gems/activerecord-4.0.3/lib/active_record/associations/collection_association.rb:152:in `block in transaction'
/home/thelinuxlich/.gem/ruby/2.1.0/gems/activerecord-4.0.3/lib/active_record/connection_adapters/abstract/database_statements.rb:202:in `block in transaction'
/home/thelinuxlich/.gem/ruby/2.1.0/gems/activerecord-4.0.3/lib/active_record/connection_adapters/abstract/database_statements.rb:210:in `within_new_transaction'
/home/thelinuxlich/.gem/ruby/2.1.0/gems/activerecord-4.0.3/lib/active_record/connection_adapters/abstract/database_statements.rb:202:in `transaction'
/home/thelinuxlich/.gem/ruby/2.1.0/gems/activerecord-4.0.3/lib/active_record/transactions.rb:209:in `transaction'
/home/thelinuxlich/.gem/ruby/2.1.0/gems/activerecord-4.0.3/lib/active_record/associations/collection_association.rb:151:in `transaction'
/home/thelinuxlich/.gem/ruby/2.1.0/gems/activerecord-4.0.3/lib/active_record/associations/collection_association.rb:460:in `create_record'
/home/thelinuxlich/.gem/ruby/2.1.0/gems/activerecord-4.0.3/lib/active_record/associations/collection_association.rb:125:in `create!'
/home/thelinuxlich/.gem/ruby/2.1.0/gems/activerecord-4.0.3/lib/active_record/associations/collection_proxy.rb:276:in `create!'
/home/thelinuxlich/.bundler/ruby/2.1.0/spree_shared-68a4871e6f6f/lib/tasks/db.rake:96:in `block (4 levels) in <top (required)>'
/home/thelinuxlich/.gem/ruby/2.1.0/gems/activerecord-4.0.3/lib/active_record/relation/delegation.rb:50:in `each'
/home/thelinuxlich/.gem/ruby/2.1.0/gems/activerecord-4.0.3/lib/active_record/relation/delegation.rb:50:in `each_with_index'
/home/thelinuxlich/.gem/ruby/2.1.0/gems/activerecord-4.0.3/lib/active_record/relation/delegation.rb:50:in `each_with_index'
/home/thelinuxlich/.bundler/ruby/2.1.0/spree_shared-68a4871e6f6f/lib/tasks/db.rake:93:in `block (3 levels) in <top (required)>'
/home/thelinuxlich/.bundler/ruby/2.1.0/spree_shared-68a4871e6f6f/lib/tasks/db.rake:30:in `block (2 levels) in <top (required)>'

URLs sometimes get an IP instead of a tenant's subdomain

Hello,

I've been using this gem for a few months in development with spree 3.0 and have been noticing this very subtle problem where sometimes the URLs in the app end up with the IP address of the server and not the tenant's subdomain. I have not had much luck in trying to debug the issue here. I've got some suspicion that the during the caching process the tenant isn't getting evaluated. If I clear the cache through spree's admin interface the correct URLs get rendered. So I wonder if this is related to issue #1?

So far my solution is to patch the spree views with _path instead of _url routes. But I'm worried that this will burn me on some other places that I haven't caught/patched yet.

If there's anything anyone can suggest as far as ways to debug this I'd greatly appreciate it. I've yet to find any way to reproduce this, so if there's any strategy on that, it would be tremendously useful, too.

Adding new stores

Everytime I want to add a new store, I will have to edit config/apartment.rb and add it to config.tenant_names, then restart the Rails app?

Install ontop of latest spree_starter template results in caching namespace race condition? on production/heroku with MEMCACHEDCLOUD_SERVERS populated

Getting this error on heroku production deploys when a memcache resource is enabled

-----> Preparing app for Rails asset pipeline
       Running: rake assets:precompile
       I, [2021-12-25T04:04:52.324657 #2170]  INFO -- sentry: ** [Raven] Sending event 0a98455ba0ee42e6b19c3f8c54e41d48 to Sentry
       rake aborted!
       ActiveRecord::ConnectionNotEstablished: ActiveRecord::ConnectionNotEstablished
       /tmp/build_e40e4bf7/vendor/bundle/ruby/3.0.0/gems/activerecord-6.1.3/lib/active_record/connection_handling.rb:323:in `connection_pool'
       /tmp/build_e40e4bf7/vendor/bundle/ruby/3.0.0/gems/activerecord-6.1.3/lib/active_record/connection_handling.rb:319:in `connection_db_config'
       /tmp/build_e40e4bf7/vendor/bundle/ruby/3.0.0/gems/ros-apartment-2.10.0/lib/apartment.rb:40:in `connection_config'

Afer https://github.com/spree-contrib/spree_shared#installation
Step #6

Looks like this specific block is the issue (Attempting to call Apartment::Tenant.current in a block in production.rb)
https://github.com/spree/spree_starter/blob/main/config/environments/production.rb#L77-L83

The normal config.cache_store line runs fine

Seems related to the second block configuring Dalli ( looking into why/if that config is necessary )

Error while running bundle exec rake spree_shared:bootstrap['store1']

Hi - I get the below error while running rake spree_shared:bootstrap['store1'].

ActiveRecord::StatementInvalid: SQLite3::SQLException: near "SCHEMA": syntax error: DROP SCHEMA IF EXISTS store2 CASCADE

Below are my spree gems.
gem 'spree', '3.0.1'
gem 'spree_gateway', github: 'spree/spree_gateway', branch: '3-0-stable'
gem 'spree_auth_devise', github: 'spree/spree_auth_devise', branch: '3-0-stable'
gem 'spree_shared', github: 'spree-contrib/spree_shared', branch: '3-0-stable'

I have created a default spree store (spree install --auto_accept) and followed the instructions in the readme.

Any help is appreciated.

Thanks

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.