{"action":"created","issue":{"url":"https://api.github.com/repos/balderdashy/sails/issues/2553","labels_url":"https://api.github.com/repos/balderdashy/sails/issues/2553/labels{/name}","comments_url":"https://api.github.com/repos/balderdashy/sails/issues/2553/comments","events_url":"https://api.github.com/repos/balderdashy/sails/issues/2553/events","html_url":"https://github.com/balderdashy/sails/pull/2553","id":54020214,"number":2553,"title":"Enable Multitenancy support on Blueprints.","user":{"login":"Glavin001","id":1885333,"avatar_url":"https://avatars.githubusercontent.com/u/1885333?v=3","gravatar_id":"","url":"https://api.github.com/users/Glavin001","html_url":"https://github.com/Glavin001","followers_url":"https://api.github.com/users/Glavin001/followers","following_url":"https://api.github.com/users/Glavin001/following{/other_user}","gists_url":"https://api.github.com/users/Glavin001/gists{/gist_id}","starred_url":"https://api.github.com/users/Glavin001/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Glavin001/subscriptions","organizations_url":"https://api.github.com/users/Glavin001/orgs","repos_url":"https://api.github.com/users/Glavin001/repos","events_url":"https://api.github.com/users/Glavin001/events{/privacy}","received_events_url":"https://api.github.com/users/Glavin001/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":10,"created_at":"2015-01-12T04:40:33Z","updated_at":"2015-01-13T18:08:01Z","closed_at":null,"pull_request":{"url":"https://api.github.com/repos/balderdashy/sails/pulls/2553","html_url":"https://github.com/balderdashy/sails/pull/2553","diff_url":"https://github.com/balderdashy/sails/pull/2553.diff","patch_url":"https://github.com/balderdashy/sails/pull/2553.patch"},"body":"## About\r\n\r\nSee https://github.com/balderdashy/waterline/pull/787\r\n\r\n### `*Do Not Merge Yet*`\r\n\r\nWaiting on pending Pull Request for Waterline: https://github.com/balderdashy/waterline/pull/787\r\n\r\n## Usage\r\n\r\n### 1. Configure your `Connection`\r\n\r\nSee [`Usage - Configure Connection`](https://github.com/balderdashy/waterline/pull/787).\r\n\r\n```javascript\r\n 'my_foo': {\r\n        adapter: 'foo',\r\n        host: 'localhost',\r\n        port: 12345,\r\n        database: 'default_database',\r\n\r\n        // === New ===\r\n        isMultiTenant: true, // Enable Multi-Tenancy feature\r\n        configForTenant: function(tenantId, config, cb) { // For Waterline\r\n          // Validate Tenant\r\n          tenantId = parseInt(tenantId);\r\n          if (tenantId >= 1 && tenantId < 10) {\r\n            config.database = \"tenant-\" + tenantId;\r\n            return cb(null, config);\r\n          } else {\r\n            // \r\n            return cb(new Error(\"Invalid tenant \" + tenantId + \"!\"));\r\n          }\r\n        }\r\n\r\n      }\r\n``` \r\n\r\n### 2. Extract your Tenant from the `req`uest\r\n\r\nCreate a simple Policy:\r\n\r\n```javascript\r\nmodule.exports = function(req, res, next) {\r\n    req.session.tenant = req.header('x-tenant');\r\n    return next();\r\n};\r\n```\r\n\r\n- In this case `req.header('x-tenant')` is where the Tenant information is stored for your request and specific server API. Feel free to change that.\r\n- `req.session.tenant` is important. This is what you set to scope the Model and their queries (`find`, `create`, `update`, `destroy`, etc) to the correct tenant.\r\n- Apply this Policy to another Controllers that have multi-tenancy enabled. See `config/policies.js`.\r\n  - Note: If you apply this Policy to a Controller that *does not support multi-tenancy* then you will receive the following error: ` [Error: Multi-Tenancy not supported with this connection's configuration]`\r\n\r\n### 3. Profit\r\n\r\nAll of your generated Blueprints (`find`, `create`, `update`, `destroy`)  will automatically apply to their correct Tenants for the request!\r\n\r\nFor a custom action:\r\n\r\n```javascript\r\nmodule.exports = {\r\n    \"customAction\": function(req, res) {\r\n        Model\r\n        .tenant(req.session.tenant) // <--- Use Tenant API!\r\n        .find({})\r\n        .exec(function(err, results) {\r\n            if (err) {\r\n                return res.serverError(err);\r\n            }\r\n            return res.json(results);\r\n        });\r\n    }\r\n};\r\n```\r\n\r\n\r\n/cc @toddmurphy @particlebanana @eubruno\r\n\r\n"},"comment":{"url":"https://api.github.com/repos/balderdashy/sails/issues/comments/69790061","html_url":"https://github.com/balderdashy/sails/pull/2553#issuecomment-69790061","issue_url":"https://api.github.com/repos/balderdashy/sails/issues/2553","id":69790061,"user":{"login":"Glavin001","id":1885333,"avatar_url":"https://avatars.githubusercontent.com/u/1885333?v=3","gravatar_id":"","url":"https://api.github.com/users/Glavin001","html_url":"https://github.com/Glavin001","followers_url":"https://api.github.com/users/Glavin001/followers","following_url":"https://api.github.com/users/Glavin001/following{/other_user}","gists_url":"https://api.github.com/users/Glavin001/gists{/gist_id}","starred_url":"https://api.github.com/users/Glavin001/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Glavin001/subscriptions","organizations_url":"https://api.github.com/users/Glavin001/orgs","repos_url":"https://api.github.com/users/Glavin001/repos","events_url":"https://api.github.com/users/Glavin001/events{/privacy}","received_events_url":"https://api.github.com/users/Glavin001/received_events","type":"User","site_admin":false},"created_at":"2015-01-13T18:08:01Z","updated_at":"2015-01-13T18:08:01Z","body":"Also I notice that you errors you reported to me are different:\r\n\r\nFirst comment from https://github.com/balderdashy/sails/pull/2553#issuecomment-69773152\r\n\r\n```\r\nDetails:  Error: Tenant is required to be specified in operation.\r\n```\r\n\r\nNext error:\r\n\r\n```\r\nerror: Sending 500 (\"Server Error\") response: \r\n TypeError: Object #<Object> has no method 'validate'\r\n```\r\n\r\nCould you please describe what requests you are sending / sample code such that it is clear what you are doing to create these very different errors."}}