0
votes

My problem is "simple", but I could not resolve it with Ember....

It is a Small Library App, with authors and books with those routes working fine

this.resource('books', function () {
    this.route('edit', {path: '/:book_id/edit'});
    this.route('show', {path: '/:book_id'});
});

this.resource('authors', function () {
    this.route('new');
    this.route('edit', {path: '/:author_id/edit'});
    this.route('show', {path: '/:author_id'});
});

Now I want to add a route which allows me to register new books, using a link from a current author template /authors/156

The route must open a books/new template, and link the new book object with his author: ie I want to show <h1>New book from {{author.name}}</h1>

What route should I add to the existing ones? How can I pass the author reference to the new book object?

2

2 Answers

0
votes

I see three ways of doing it:

  1. Put it under the books resource and require the author as a route parameter:

    this.resource('books', function() {
        this.route('new', { path: '/new/:author_id' });
    });
    
  2. Put the route under the books resource, but put the author in a query parameter instead.

    this.resource('books', function() {
        // Declare required query parameter on controller for `new` route
        this.route('new');
    });
    
  3. Put the route under authors and require the author in the URL:

    this.resource('authors', function() {
        this.route('new_book', { path: '/:author_id/new_book' });
    });
    

I would suggest the third option, as I think it's the cleanest. In your controller, you can create a new book fairly easily:

export default Ember.Controller.extend({
    actions: {
        createBook: function() {
            var author = this.get('model');
            var book = this.store.createRecord('book', {
                author: author,
                ...
            });

            book.save();
        }
    }
});
0
votes

I've tried and succeed with the second suggested method, query params.

Router:

this.resource('books', function () {
    this.route('new');
    this.route('show', {path: '/:book_id'});
};

Route

App.BooksNewRoute = Ember.Route.extend({
    queryParams: {
        author_id: {
            refreshModel: true
        }
    },
    model: function (params) {
        var newBook = this.store.createRecord('book');
        this.store.find('author', params.author_id).then(function (author) {
            newBook.set('author', author);
        });
        return newBook;
    }
});

and Controller

App.BooksNewController = Ember.ObjectController.extend({
    queryParams: ['author_id'],
    author_id: null,
    actions: {
        save: function () {
            var controller = this;
            this.get('model').save().then(function (book) {
                controller.transitionToRoute('books.show', book);
            }, function (error) {
                console.error(error);
            });
        },
        cancel: function () {
            this.get('model').rollback();
            this.transitionToRoute('index');
        }
    }
});