README.md in ember-cli-rails-0.4.3 vs README.md in ember-cli-rails-0.5.0
- old
+ new
@@ -19,252 +19,292 @@
For example, end-to-end tests with frameworks like Cucumber should just work.
You should still be able leverage the asset pipeline, and all the conveniences
that Rails offers. And you should get all the new goodies like ES6 modules and
Ember CLI addons too! Without further ado, let's get in there!
+**EmberCLI-Rails Supports EmberCLI 1.13.x and later.**
+
## Installation
-Firstly, you'll have to include the gem in your `Gemfile` and `bundle install`
+Add the following to your `Gemfile`:
```ruby
gem "ember-cli-rails"
```
-Then you'll want to configure your installation by adding an `ember.rb`
-initializer. There is a generator to guide you, run:
+Then run `bundle install`:
-```shell
-rails generate ember-cli:init
+```bash
+$ bundle install
```
-This will generate an initializer that looks like the following:
+## Usage
+First, generate the gem's initializer:
+
+```bash
+$ rails generate ember-cli:init
+```
+
+This will create the following initializer:
+
```ruby
-EmberCLI.configure do |c|
+# config/initializers/ember.rb
+
+EmberCli.configure do |c|
c.app :frontend
end
```
-##### options
+The initializer assumes that your Ember application exists in
+`Rails.root.join("frontend")`.
-- `app` - this represents the name of the Ember CLI application.
+If this is not the case, you could
-- `build_timeout` - seconds to allow Ember to build the application before
- timing out
+* move your existing Ember application into `Rails.root.join("frontend")`
+* configure `frontend` to look for the Ember application in its current
+ directory:
+```rb
+c.app :frontend, path: "~/projects/my-ember-app"
+```
+
+* generate a new Ember project:
+
+```bash
+$ ember new frontend
+```
+
+**Initializer options**
+
+- `name` - this represents the name of the Ember CLI application.
+
- `path` - the path where your Ember CLI application is located. The default
value is the name of your app in the Rails root.
-- `enable` - a lambda that accepts each request's path. The default value is a
- lambda that returns `true`.
-
```ruby
-EmberCLI.configure do |c|
- c.app :adminpanel # path is "<your-rails-root>/adminpanel"
+EmberCli.configure do |c|
+ c.app :adminpanel # path defaults to `Rails.root.join("adminpanel")`
c.app :frontend,
- path: "/path/to/your/ember-cli-app/on/disk",
- enable: -> path { path.starts_with?("/app/") }
+ path: "/path/to/your/ember-cli-app/on/disk"
end
```
-Once you've updated your initializer to taste, install Ember CLI if it is not already installed, and use it to generate your Ember CLI app in the location/s specified in the initializer. For example:
+Next, install the [ember-cli-rails-addon][addon]:
-```sh
-cd frontend
-ember init
+```bash
+$ cd path/to/frontend
+$ npm install --save-dev ember-cli-rails-addon
```
-You will also need to install the [ember-cli-rails-addon](https://github.com/rondale-sc/ember-cli-rails-addon). For each of your Ember CLI applications, run:
+Be sure that the addon's [`MAJOR` and `MINOR` version][semver] matches the gem's
+`MAJOR` and `MINOR` versions.
-```sh
-npm install --save-dev ember-cli-rails-addon@0.0.13
+For instance, if you're using the `0.5.x` version of the gem, specify
+`~> 0.5.0` ion in your Ember app's `package.json`:
+
+```json
+{
+ "devDependencies": {
+ "ember-cli-rails-addon": "~> 0.5.0"
+ }
+}
```
-And that's it! You should now be able to start up your Rails server and see your Ember CLI app.
+[addon]: https://github.com/rondale-sc/ember-cli-rails-addon/
+[semver]: http://semver.org/
-### Multiple Ember CLI apps
+Next, configure Rails to route requests to the `frontend` Ember application:
-In the initializer you may specify multiple Ember CLI apps, each of which can be
-referenced with the view helper independently. You'd accomplish this like so:
+```rb
+# config/routes.rb
-```ruby
-EmberCLI.configure do |c|
- c.app :frontend
- c.app :admin_panel, path: "/somewhere/else"
+Rails.application.routes.draw do
+ mount_ember_app :frontend, to: "/"
end
```
-## Usage
+Ember requests will be set `params[:ember_app]` to the name of the application.
+In the above example, `params[:ember_app] == :frontend`.
-First, specify in your controller that you don't want to render the layout
-(since EmberCLI's `index.html` is a fully-formed HTML document):
+**Routing options**
+* `to` - The path to handle as an Ember application. This will only apply to
+ `format: :html` requests. Additionally, this will handle child routes as well.
+ For instance, mounting `mount_ember_app :frontend, to: "/frontend"` will handle a
+ `format: :html` request to `/frontend/posts`.
+* `controller` - Defaults to `"ember_cli/ember"`
+* `action` - Defaults to `"index"`
+
+You should now be able to boot your Rails application, navigate to the `root`
+route, and see your EmberCLI app!
+
+## Configuring the Ember controller
+
+By default, routes defined by `ember_app` will be rendered with the internal
+`EmberCli::EmberController`. The `EmberCli::EmberController` renders the Ember
+application's `index.html` and injects the Rails-generated CSRF tags into the
+`<head>`.
+
+To override this behavior, specify the `controller` and `action` options:
+
```rb
-# app/controllers/application.rb
-class ApplicationController < ActionController::Base
- def index
- render layout: false
- end
+# config/routes
+
+Rails.application.routes.draw do
+ mount_ember_app :frontend, to: "/", controller: "application", action: "index"
end
```
-To render the EmberCLI generated `index.html` into the view,
-use the `include_ember_index_html` helper:
+To serve the EmberCLI generated `index.html`, use the `render_ember_app`
+helper in your view:
-
```erb
-<!-- /app/views/application/index.html.erb -->
-<%= include_ember_index_html :frontend %>
+<!-- app/views/application/index.html.erb -->
+<%= render_ember_app :frontend %>
```
To inject markup into page, pass in a block that accepts the `head`, and
(optionally) the `body`:
```erb
-<!-- /app/views/application/index.html.erb -->
-<%= include_ember_index_html :frontend do |head| %>
+<!-- app/views/application/index.html.erb -->
+<%= render_ember_app :frontend do |head| %>
<% head.append do %>
<%= csrf_meta_tags %>
<% end %>
<% end %>
```
-The asset paths will be replaced with asset pipeline generated paths.
+When serving the EmberCLI generated `index.html`, don't use Rails' layout HTML:
-*NOTE*
+```rb
+# app/controllers/application.rb
+class ApplicationController < ActionController::Base
+ def index
+ render layout: false
+ end
+end
+```
-This helper **requires** that the `index.html` file exists.
-
-If you see `Errno::ENOENT` errors in development, your requests are timing out
-before EmberCLI finishes compiling the application.
-
-To prevent race conditions, increase your `build_timeout` to ensure that the
-build finishes before your request is processed.
-
### Rendering the EmberCLI generated JS and CSS
In addition to rendering the EmberCLI generated `index.html`, you can inject the
`<script>` and `<link>` tags into your Rails generated views:
```erb
-<!-- /app/views/application/index.html.erb -->
+<!-- app/views/application/index.html.erb -->
<%= include_ember_script_tags :frontend %>
<%= include_ember_stylesheet_tags :frontend %>
```
-### Other routes
+### Multiple Ember CLI apps
-Rendering Ember applications at routes other than `/` requires additional setup to avoid an Ember `UnrecognizedURLError`.
+In the initializer you may specify multiple Ember CLI apps, each of which can be
+referenced with the view helper independently. You'd accomplish this like so:
-For instance, if you had Ember applications named `:frontend` and `:admin_panel` and you wanted to serve them at `/frontend` and `/admin_panel`, you would set up the following Rails routes:
+```ruby
+EmberCLI.configure do |c|
+ c.app :frontend
+ c.app :admin_panel, path: "/somewhere/else"
+end
+```
+Rendering Ember applications at routes other than `/` requires additional setup
+to avoid an Ember `UnrecognizedURLError`.
+
+For instance, if you had Ember applications named `:frontend` and
+`:admin_panel` and you wanted to serve them at `/frontend` and `/admin_panel`,
+you would set up the following Rails routes:
+
```rb
# /config/routes.rb
Rails.application.routes.draw do
- root 'application#index'
- get 'frontend' => 'frontend#index'
- get 'admin_panel' => 'admin_panel#index'
+ mount_ember_app :frontend, to: "/frontend"
+ mount_ember_app :admin_panel, to: "/admin_panel"
end
-
-# /app/controllers/frontend_controller.rb
-class FrontendController < ActionController::Base
- def index
- render :index
- end
-end
-
-# /app/controllers/admin_panel_controller.rb
-class AdminPanelController < ActionController::Base
- def index
- render :index
- end
-end
```
-Additionally, you would have to modify each Ember app's `baseURL` to point to the correct route:
+You must modify each Ember app's `baseURL` to point to the correct route:
```javascript
-/* /app/frontend/config/environment.js */
+// app/frontend/config/environment.js
+
module.exports = function(environment) {
var ENV = {
modulePrefix: 'frontend',
environment: environment,
baseURL: '/frontend', // originally '/'
...
}
}
-/* /app/admin_panel/config/environment.js */
+// app/admin_panel/config/environment.js
+
module.exports = function(environment) {
var ENV = {
modulePrefix: 'admin_panel',
environment: environment,
baseURL: '/admin_panel', // originally '/'
...
}
}
```
-Lastly, you would configure each app's `router.js` file so that `rootURL` points to the `baseURL` you just created:
+Finally, configure each app's `router.js` file so that `rootURL` refers to the
+new `baseURL`:
+
```javascript
/* app/frontend/app/router.js */
var Router = Ember.Router.extend({
rootURL: config.baseURL, // add this line
location: config.locationType
});
```
-Repeat for `app/admin_panel/app/router.js`. Now your Ember apps will render properly at the alternative routes.
+Repeat the process for `admin_panel/app/router.js`.
+
## CSRF Tokens
Your Rails controllers, by default, are expecting a valid authenticity token to be submitted with non-`GET` requests.
Without it you'll receive a `422 Unprocessable Entity` error, specifically: `ActionController::InvalidAuthenticityToken`.
In order to add that token to your requests, you need to add into your template:
```erb
-<!-- /app/views/application/index.html.erb -->
-# ... your ember script and stylesheet includes ...
-<%= csrf_meta_tags %>
+<!-- app/views/application/index.html.erb -->
+<%= render_ember_app :frontend do |head| %>
+ <% head.append do %>
+ <%= csrf_meta_tags %>
+ <% end %>
+<% end %>
```
-This will add the tokens to your page.
+The default `EmberCli::EmberController` and its accompanying view handle this
+for you by default.
-You can then override the application `DS.RESTAdapter` (or whatever flavor of adapter you're using) to send that token with the requests:
+However, if you specify your own controller, make sure to append CSRF tags to
+your view's `<head>`.
-```js
-// path/to/your/ember-cli-app/app/adapters/application.js
-import DS from 'ember-data';
-import $ from 'jquery';
+The [ember-cli-rails-addon][addon] addon will inject an initializer into your
+app to set outgoing requests' `X-CSRF-TOKEN` header to the value injected by
+Rails.
-export default DS.RESTAdapter.extend({
- headers: {
- "X-CSRF-Token": $('meta[name="csrf-token"]').attr('content')
- }
-});
-```
+### Integrating with Rake
-## Ember Test Suite
+EmberCLI Rails exposes the `ember:test` Rake task to execute Ember's test suite.
-To run an Ember app's tests in a browser, mount the `EmberCLI::Engine`:
+If you're using Rake to run your test suite, make sure to configure your test
+task to depend on `ember:test`.
-```ruby
-# config/routes.rb
+For example, to configure a bare `rake` command to run both RSpec and Ember test
+suites, configure the `default` task to depend on both `spec` and `ember:test`.
-Rails.application.routes.draw do
- mount EmberCLI::Engine => "ember-tests" if Rails.env.development?
-
- root "application#index"
-end
+```rb
+task default: [:spec, "ember:test"]
```
-Ember tests are served based on the route you mount the Engine on (in this
-example, `/ember-tests`) and the name of the Ember app.
-
-For example, to view tests of the `frontend` app, visit
-`http://localhost:3000/ember-tests/frontend`.
-
## Serving from multi-process servers in development
If you're using a multi-process server ([Puma], [Unicorn], etc.) in development,
make sure it's configured to run a single worker process.
@@ -324,10 +364,25 @@
$ heroku config:unset SKIP_EMBER
```
You should be ready to deploy.
+The generator will disable Rails' JavaScript compression by declaring:
+
+```rb
+config.assets.js_compressor = nil
+```
+
+This is recommended, but might not work for projects that have both Asset
+Pipeline and EmberCLI generated JavaScript.
+
+To reverse this change, reconfigure Sprockets to use the `uglifier` gem:
+
+```rb
+config.assets.js_compressor = :uglifier
+```
+
**NOTE** Run the generator each time you introduce additional EmberCLI
applications into the project.
[buildpack]: https://devcenter.heroku.com/articles/using-multiple-buildpacks-for-an-app#adding-a-buildpack
@@ -402,10 +457,23 @@
Alternatively, if you want to override the default behavior in any given Rails
environment, you can manually set the `config.use_ember_middleware` and
`config.use_ember_live_recompilation` flags in the environment-specific config
file.
+### `ASSET_HOST`
+
+Used by [the addon][addon] during fingerprinting.
+
+When compiling an Ember app named `"frontend"` from within Rails,
+the addon will prepend the generated asset paths with:
+
+ ${ASSET_HOST}/assets/frontend/
+
+### `CDN_HOST`
+
+Behaves the same way as `ASSET_HOST`, acting as a fallback.
+
### `RAILS_ENV`
While being managed by EmberCLI Rails, EmberCLI process will have
access to the `RAILS_ENV` environment variable. This can be helpful to detect
the Rails environment from within the EmberCLI process.
@@ -448,10 +516,10 @@
If you have the jQuery assets included on your page you may want to exclude them
from the Ember distribution. You can do so by setting the `exclude_ember_deps`
option like so:
```ruby
-EmberCLI.configure do |c|
+EmberCli.configure do |c|
c.app :frontend, exclude_ember_deps: "jquery"
c.app :admin_panel, exclude_ember_deps: ["jquery", "handlebars"]
end
```