# Sandboxy - virtual data-oriented environments for Rails [![Gem Version](https://badge.fury.io/rb/sandboxy.svg)](https://badge.fury.io/rb/sandboxy) Sandboxy allows you to use virtual data-oriented environments inside a Rails application while being able to switch in between at runtime. It achieves that by using a combination of Rack Middleware and ActiveRecord. --- ## Table of Contents * [Installation](#installation) * [Usage](#usage) * [Setup](#setup) * [Configuration](#configuration) * [Sandboxed methods](#sandboxed-methods) * [Sandboxy methods](#sandboxy-methods) * [Switching environments](#switching-environments) * [Sandbox & APIs](#sandbox--apis) * [To Do](#to-do) * [Contributing](#contributing) * [Contributors](#contributors) * [Semantic Versioning](#semantic-versioning) * [License](#license) --- ## Installation Sandboxy works with Rails 4.0 onwards. You can add it to your `Gemfile` with: ```ruby gem 'sandboxy' ``` And then execute: $ bundle Or install it yourself as: $ gem install sandboxy If you always want to be up to date fetch the latest from GitHub in your `Gemfile`: ```ruby gem 'sandboxy', github: 'slooob/sandboxy' ``` Now run the generator: $ rails g sandboxy You can specify your applications default environment by passing `--default live` or `--default sandbox`. Learn more about switching environments [here](#switching-environments). To set that your app should retain it's environment at runtime on new requests pass `--retain_environment true`. You can always update your [configuration](#configuration) later. To wrap things up, migrate the changes into your database: $ rails db:migrate **Note:** Use `rake db:migrate` instead if you run Rails < 5. This will create a configuration file under `config/sandboxy.yml` as well as a migration file and the `Sandbox` model. ## Usage ### Setup Add Sandboxy to the models where you want to separate live & sandbox records: ```ruby class Foo < ApplicationRecord sandboxy end ``` In most use cases you would want to add sandboxy to a lot of ActiveRecord models if not all. To simplify that you could create a new class and let all your models inherit from it: ```ruby class SharedSandbox < ApplicationRecord sandboxy end class Foo < SharedSandbox end ``` ### Configuration In `config/sandboxy.yml` you define your app's default environment. This can be either set to `live` or `sandbox`. It defaults to `live`. Now this default gets refreshed before every new request. To retain any environment you [switched in at runtime](#switching-environments), you need to set `retain_environment` to `true`. Defaults to `false`. ### Sandboxed methods By default you can only access records belonging to the current environment (`live` or `sandbox`): ```ruby $sandbox = true Foo.all # => returns all sandbox foo's ``` Now to access the records belonging to a certain group regardless of your current environment, you can use: ```ruby Foo.live # => returns all live foo's Foo.sandboxed # => returns all sandbox foo's Foo.desandbox # => returns all foo's ``` Let's check to which environment this `Foo` belongs: ```ruby foo = Foo.create! foo.live? # => false foo.sandboxed? # => true ``` You should keep in mind that when you create a new record, it will automatically belong to your app's current environment. Don't worry, you can move records between environments: ```ruby foo.make_live foo.live? # => true foo.make_sandboxed foo.sandboxed? # => true ``` ### Sandboxy methods To access your default environment setting: ```ruby Sandboxy.environment # => 'live' / 'sandbox' Sandboxy.sandbox? # => true / false Sandboxy.live? # => true / false ``` **Note:** `Sandboxy.environment` does *NOT* return the apps current environment. For that use the [`$sandbox` variable](#switching-environments) instead. You can also access whether your app retains your environment throughout request: ```ruby Sandboxy.retain_environment # => true / false ``` ### Switching environments At runtime you can always switch environments by using the `$sandbox` variable anywhere in your application. Set it to `true` to enable the `sandbox` environment. Set it to `false` to enable the `live` environment. That makes Sandboxy super flexible. #### Sandbox & APIs It's flexibility allows Sandboxy to work really well with APIs. Typically an API provides two sets of authentication credentials for a consumer - one for live access and one for sandbox/testing. Whenever you authenticate your API's consumer, just make sure to set the `$sandbox` variable accordingly to the credential the consumer used. From thereon, Sandboxy will make sure that your consumer only reads & updates data from the environment he is in. --- ## To Do * Leave your suggestions [here](https://github.com/slooob/sandboxy/issues/new) --- ## Contributing We hope that you will consider contributing to Sandboxy. Please read this short overview for some information about how to get started: [Learn more about contributing to this repository](https://github.com/slooob/sandboxy/blob/master/CONTRIBUTING.md), [Code of Conduct](https://github.com/slooob/sandboxy/blob/master/CODE_OF_CONDUCT.md) ### Contributors Give the people some :heart: who are working on this project. See them all at: https://github.com/slooob/sandboxy/graphs/contributors ### Semantic Versioning Sandboxy follows Semantic Versioning 2.0 as defined at http://semver.org. ## License MIT License Copyright (c) 2017 Slooob Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.