# ember/template-no-route-action
💼 This rule is enabled in the 📋 `template-lint-migration` [config](https://github.com/ember-cli/eslint-plugin-ember#-configurations).
> **HBS Only**: This rule applies to classic `.hbs` template files only (loose mode). It is not relevant for `gjs`/`gts` files (strict mode), where these patterns cannot occur.
This rule disallows the usage of `route-action`.
[ember-route-action-helper](https://github.com/DockYard/ember-route-action-helper) was a popular addon used to add actions to a route without creating a separate controller. Given the changes in Ember since ember-route-action-helper was a widely used pattern, controllers are now encouraged and we want to discourage the use of route-action.
Most route actions should either be sent to the controller first or encapsulated within a downstream component instead. We should never be escaping the DDAU hierarchy to lob actions up to the route.
## Examples
This rule **forbids** the following:
```hbs
```
```hbs
```
```hbs
{{custom-component onUpdate=(route-action 'updateFoo')}}
```
```hbs
{{custom-component onUpdate=(route-action 'updateFoo' 'bar')}}
```
With the given route:
```js
// app/routes/foo.js
export default class extends Route {
@action
updateFoo(baz) {
// ...
}
}
```
This rule **allows** the following:
```hbs
```
```hbs
```
```hbs
{{custom-component onUpdate=this.updateFoo}}
```
```hbs
{{custom-component onUpdate=(fn this.updateFoo 'bar')}}
```
With the given controller:
```js
// app/controllers/foo.js
export default class extends Controller {
@action
updateFoo(baz) {
// ...
}
}
```
## Migration
The example below shows how to migrate from route-action to controller actions.
### Before
```js
// app/routes/posts.js
export default class extends Route {
model(params) {
return this.store.query('post', { page: params.page });
}
@action
goToPage(pageNum) {
this.transitionTo({ queryParams: { page: pageNum } });
}
}
```
```js
// app/controllers/posts.js
export default class extends Controller {
queryParams = ['page'];
page = 1;
}
```
```hbs
{{#each @model as |post|}}
{{/each}}
```
### After
```js
// app/routes/posts.js
export default class extends Route {
model(params) {
return this.store.query('post', { page: params.page });
}
}
```
```js
// app/controllers/posts.js
export default class extends Controller {
queryParams = ['page'];
page = 1;
@action
goToPage(pageNum) {
this.transitionToRoute({ queryParams: { page: pageNum } });
}
}
```
```hbs
{{#each @model as |post|}}
{{/each}}
```
## References
- [ember-route-action-helper](https://github.com/DockYard/ember-route-action-helper)
- [Ember guides/Controllers](https://guides.emberjs.com/release/routing/controllers/)
- [Ember Best Practices: What are controllers good for?](https://dockyard.com/blog/2017/06/16/ember-best-practices-what-are-controllers-good-for)