Video

Want to see the full-length video right now for free?

Notes

Advanced Models and Relationships - Part 1

Now that we've refactored notes to be their own model, let's add todo lists.

  • First let's generate a new model rails g model TodoList
  • Extract the StickNote relation to Note and the touch callback to a new Rails concern from the

    • Name the new concer NoteBody

      module NoteBody extend ActiveSupport::Concern

      included do has_one :note, as: :body after_save :touch_note end

      private

      def touch_note note.touch end end

    • Mix the new NoteBody module into the StickyNote model

    • Mix the new NoteBody module into the TodoList model

  • Next we need to generate a TodoItem model rails g model TodoItem todo_list:belongs_to title:string complete:boolean

    • Modify the migration to default complete to false
  • Add dependent: destroy to the has_many relationship between TodoList and TodoItem

  • Add touch: true to the belongs_to relationship between TodoItem and TodoList

  • Update the seeds file to have one note, and one todo list with 2 items

    Note.create([
      {
        title: 'a simple note',
        body: StickyNote.new(content: "Don't gorget to make a list")
      },
      {
        title: 'A more complex todo list',
        body: TodoList.new(
          todo_items: [
            TodoItem.new(title: 'make a second todo item', complete: true),
            TodoItem.new(title: 'Make another todo list', complete: false),
            TodoItem.new(title: 'DSICO PARTY!', complete: false)
          ]
        )
      }
    ])
    
  • rake db:reset

Polymorphism in the front-end

  • The page is crashing as soon as we try to parse a todo list
  • We can solve this in the short term by using the existential operator ? after sticky_note data.content = data.body.sticky\_note?.content || ""

  • The page is now loading, but has an empty text field rather than a todo list

  • Create an empty TodoList Backbone model

  • Rename the Backbone Note model to StickyNote

  • In the Notes collection change the model to a function

    • Return a new instance of a model from this function

      (data) -> if data.body.type == "sticky_note" new App.Models.StickyNote(arguments...) else new App.Models.TodoList(arguments...)

  • Now we extract the text area from the body div in the show.jst.eco file

  • Next we create a Backbone TodoList view, and have its render method append 'Hello from the todo list view'

  • In the ShowNote view we need to initialize the correct note body based on type

    • First define a viewFor(model) method on ScratchPad that grabs the correct view class, and returns a new instance

      viewFor: (model) -> modelClass = model.constructor.name viewClass = @Views[modelClass] new viewClass(model: model)

    • Then in the initialize method of the ShowNote view call the new method to get an instance of the correct view

    • Use the setElement method in the ShowNote view's render method to append the note body view to the body div in the show template

  • We're not quite done the add note button is broken.

  • In the AddActions view we need to change the code that appends a new Note to our Notes collection

    • Instead of adding an empty object we need to add an instance of a Note
    • For now let's hardcode a StickyNote
    • @collection.add(new App.Models.StickyNote)
  • Commit!