In short...
When building an Ember.js app to persist to a Rails app, how should I handle Rails routing/views? I would think I just need Rails to render the application.html.erb layout so the Ember.js app initializes and handles the routing/view/templates.
Details:
Specifically if I visit localhost:3000, before my Ember.js app has a chance to initialize, Rails hits the "index" action on the projects controller. It will complain about a missing index template. I have no index.html.erb view as my Ember.js app has a view/template for it.
Should I be creating blank views for the Rails app? Should my Rails controller actions be returning something to prevent it from rendering a view? Or am I expected to build normal Rails views to go alongside the Ember.js app views/templates?
If I create a blank projects/index.html.erb and visit localhost:3000, Rails will render it, Ember.js will initialize and handle routing from then on. However, if I visit localhost:3000/projects/new directly Rails complains about not having a new action in the projects controller. I do not have "new" action on the projects controller on the Rails side as I don't need it. My Ember.js app is handling that view/template.
Ultimately I'm just unsure of what convention is expected to use Ember.js along side a Rails app.
Thank you for the help and reading this far...
Edit:
I left out the detail that I'm attempting to use the Ember.js Router's ability to use pushState history. This would leave me non-hashbang URL's. This is one reason why I'm having issues dealing with Rails competing to route my application.
Rails Application Layout:
<html>
<body>
<section id="design-archive"></section>
</body>
</html>
Ember.js App:
@DA = Em.Application.create
name: 'Design Archive'
VERSION: '0.1'
rootElement: '#design-archive'
ApplicationController: Em.Controller.extend()
ApplicationView: Em.View.extend
templateName: 'application'
DA.initialize(DA.Router)
Rails Routes:
DesignArchive::Application.routes.draw do
resources :clients, :only => [:new, :create, :index, :show, :destroy]
resources :projects, :only => [:new, :create, :index, :show, :destroy]
root :to => 'projects#index'
end
Ember.js Routes:
DA.Router = Em.Router.create
location: 'history'
root: Em.Route.extend
index: Em.Route.extend
route: '/'
redirectsTo: 'projects'
# Actions
doProjects: (router) ->
router.transitionTo('projects')
doProjectsNew: (router) ->
router.transitionTo('newProject')
# Routes
projects: Em.Route.extend
route: '/projects'
index: Em.Route.extend
router: '/'
connectOutlets: (router) ->
router.get('applicationController').connectOutlet('projects', DA.Project.find())
showProject: Em.Route.transitionTo('project')
project: Em.Route.extend
route: '/projects/:project_id'
connectOutlets: (router, project) ->
router.get('applicationController').connectOutlet('project', project)
projectsIndex: Em.Route.transitionTo('projects')
newProject: Em.Route.extend
route: '/projects/new'
connectOutlets: (router) ->
router.get('applicationController').connectOutlet('projectsNew')
Rails Controller:
class ProjectsController < ApplicationController
def index
@projects = Project.all
respond_to do |format|
format.html
format.json { render json: @projects }
end
end
end
You can have a catch-all route which bootstraps your Ember app.
Here's a simplified example from one of my apps:
App::Application.routes.draw do
match "/login" => "sessions#new", :via => :get, :as => :login
match "/login" => "sessions#create", :via => :post
match "/logout" => "sessions#destroy", :via => :post, :as => :logout
match "/attachments/:id" => "attachments#download"
match "/avatars/:id" => "avatars#show"
root :to => 'pages#bootstrap'
# anything not matched by the above should be served the bootstrap
match "/*path" => "pages#bootstrap"
end
This has the downside of returning 200
success instead of 404
errors when going to completely invalid URLs, as the Rails app doesn't know anything about the URL structure of the Ember app.
If you wanted to avoid that you could replicate your Ember URL structure in the routes and just point everything valid through to the bootstrap route instead of using the catch-all.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With