0

I am learning Ember.js as we speak and what I am trying to do is to integrate it into a Rails application (vanilla app, just for playing around), since most of the time I'm working with Rails. So far so good, I managed to install it (I am using ember-rails), but I encountered a small problem and it seems I cannot figure it out, even if I watched (I suppose) every tutorial about Ember and Rails out there.

So, the problem is that I cannot make the router pass any kind of data to the view/template. I even hardcoded there a JSON object (and not rely on the adapter) to see if this works, but with no success. So, my code looks like this:

Rails Gemfile Gemfile:

ruby "1.9.3"

gem 'rails', '3.2.16'
gem 'sqlite3'
gem 'jquery-rails'
gem 'ember-rails'
gem 'ember-source'
gem 'pg'

group :assets do
  gem 'sass-rails',   '~> 3.2.3'
  gem 'coffee-rails', '~> 3.2.1'

  # See https://github.com/sstephenson/execjs#readme for more supported runtimes
  gem 'therubyracer', :platforms => :ruby

  gem 'uglifier', '>= 1.0.3'
end

Rails controller app/controllers/users_controller.rb:

class UsersController < ApplicationController
  def index
    @a_users = User.all

    respond_to do |format|
      format.html
      format.json {render :json => @a_users}
    end
  end
end

Rails model app/models/users.rb:

class User < ActiveRecord::Base
  validates :first_name, :presence => true
  validates :last_name, :presence => true
end

Rails serializer app/serializers/user_serializer.rb:

class UserSerializer < ActiveModel::Serializer
  attributes :first_name, :last_name
end

Rails routes config/routes.rb

NewEmberOnRails::Application.routes.draw do
  root :to => 'home#index'
  resources :users
end

And this pretty much covers the Rails part. If I go and visit localhost:3000/users.json I get a nice formatted JSON object on this format (consider I have a John Doe user in the database): {"users":[{"first_name":"John","last_name":"Doe"}]}

The Ember.js part, I have written as following:

Ember store app/assets/javascripts/store.js

NewEmberOnRails.Store = DS.Store.extend({
  // Override the default adapter with the `DS.ActiveModelAdapter` which
  // is built to work nicely with the ActiveModel::Serializers gem.
  adapter: DS.ActiveModelAdapter
  // revision: 11,
  // url: 'http://localhost:3000'
});

I even played around with revision and url but nothing.

Ember router app/assets/javascripts/router.js

NewEmberOnRails.Router.map(function() {
  return this.resource('users');
});

Ember route app/assets/javascripts/route.rb

NewEmberOnRails.UsersRoute = Ember.Route.extend({
  model: function() {
    // return this.get('store').find('user');
    return {users: [{
      first_name: "John",
      last_name: "Doe"
    }, {
      first_name: "Big",
      last_name: "Bang"
    }]};
  }
});

As you can see, I've commented the store here, and returned a hardcoded object here, but nothing.

Ember controller app/assets/javascripts/controller/users.js

NewEmberOnRails.usersController = Ember.Controller.extend({
  resourceType: NewEmberOnRails.User
});

Ember model app/assets/javascripts/model/user.js

var attr = DS.attr;

NewEmberOnRails.User = DS.Model.extend(
  first_name = attr(),
  last_name = attr()
);

And finally, the views, Rails and Ember together (I guess I'm doing something wrong here, but I cannot figure it out what):

Rails users view app/views/users/index.html.erb

<h1>Users</h1>

<script type="text/x-handlebars">
  {{ view NewEmberOnRails.ListUsersView }}
</script>

So, this is calling the Ember view, here (app/assets/javascripts/views/users/list.js):

NewEmberOnRails.ListUsersView = Ember.View.extend({
  templateName: 'users/users',
  usersBinding: 'NewEmberOnRails.usersController'
});

That is using the users template here (app/assets/javascripts/template/users/users.handlebars):

{{#each users}}
  {{view NewEmberOnRails.ShowUserView userBinding="this"}}
{{else}}
  No users!
{{/each}}

Now, in ShowUserView I have (app/assets/javascripts/views/users/show.js):

NewEmberOnRails.ShowUserView = Ember.View.extend({
  templateName: 'users/show'
});

And is rendering this template (app/assets/javascripts/templates/users/show.handlebars)

First Name: {{user.first_name}}

So, to wrap up everything... when I access localhost:3000/users I only get No users!, witch lead me to two possibilities:

  1. I do not have any users array at the time I'm iterating through it in app/assets/javascripts/template/users/users.handlebars
  2. I have it, but is empty, so there is a problem between the route and my views/templates.

Does anybody have any idea?

  • What versions of ember/ember data are you using? Does the app attempt a network request to the endpoint? If so is it hitting `users` or `users.json`? – Kingpin2k Jan 12 '14 at 18:24
  • Do you get any plain html from your ember views? I don't see an Application being created – Kingpin2k Jan 12 '14 at 18:28
  • I am using `ember-rails` version `0.14.1`. This gives me Ember version `1.3.0`, Ember Data version `0.14`, all on jQuery `1.10.2` (from `jquery-rails 3.0.4`). No, I forgot to mention this. The app do not attempt any request when hitting `users`. The app is created in `app/assets/javascripts/application.js`. Is something like `NewEmberOnRails = Ember.Application.create();`. There are no errors returned from client side. –  Jan 12 '14 at 18:52

1 Answers1

0

You can do it however you wish, of course, but if it were mine, I would have my route return an array and make my controller extend ArrayController. Seems simpler and will match what you are really going to get from the store (collection of User). Unless you really want to return a single object containing an array, this is counter to 'normal' Ember Data usage--

In the code in NewEmberOnRails.UsersRoute, you have commented out the store.find and replaced it with something that is not the same thing... Try this:

NewEmberOnRails.UsersRoute = Ember.Route.extend({
  model: function() {
    // return this.get('store').find('user');
    return [{
      first_name: "John",
      last_name: "Doe"
    }, {
      first_name: "Big",
      last_name: "Bang"
    }];
  }
});

and:

NewEmberOnRails.usersController = Ember.ArrayController.extend({
    resourceType: NewEmberOnRails.User
});
Steve H.
  • 6,912
  • 2
  • 30
  • 49