Commit 33bce064

mo khan <mo@mokhan.ca>
2014-06-15 06:59:59
wire up backbone work to display my cakes.
1 parent dd49417
app/assets/javascripts/backbone/models/cake.js.coffee
@@ -6,6 +6,7 @@ class Cake.Models.Cake extends Backbone.Model
     watermark: null
     story: null
 
+
 class Cake.Collections.CakesCollection extends Backbone.Collection
   model: Cake.Models.Cake
-  url: '/cakes'
+  url: '/api/v1/cakes'
app/assets/javascripts/backbone/models/photo.js.coffee
@@ -0,0 +1,13 @@
+class Cake.Models.Photo extends Backbone.Model
+  paramRoot: 'photo'
+
+  defaults:
+    thumb_url: null
+    large_url: null
+
+class Cake.Collections.PhotosCollection extends Backbone.Collection
+  model: Cake.Models.Photo
+  url: '/api/v1/cakes/1/photos'
+
+  initialize: (options) ->
+    console.log(options)
app/assets/javascripts/backbone/routers/cakes_router.js.coffee
@@ -1,7 +1,8 @@
 class Cake.Routers.CakesRouter extends Backbone.Router
   initialize: (options) ->
     @cakes = new Cake.Collections.CakesCollection()
-    @cakes.reset options.cakes
+    @cakes.fetch(reset: true).done ->
+      Backbone.history.start()
 
   routes:
     "new"      : "newCake"
@@ -20,7 +21,6 @@ class Cake.Routers.CakesRouter extends Backbone.Router
 
   show: (id) ->
     cake = @cakes.get(id)
-
     @view = new Cake.Views.Cakes.ShowView(model: cake)
     $("#cakes").html(@view.render().el)
 
app/assets/javascripts/backbone/routers/photos_router.js.coffee
@@ -0,0 +1,31 @@
+class Cake.Routers.PhotosRouter extends Backbone.Router
+  initialize: (options) ->
+    @photos = new Cake.Collections.PhotosCollection()
+    @photos.reset options.photos
+
+  routes:
+    "new"      : "newPhoto"
+    "index"    : "index"
+    ":id/edit" : "edit"
+    ":id"      : "show"
+    ".*"        : "index"
+
+  newPhoto: ->
+    @view = new Cake.Views.Photos.NewView(collection: @photos)
+    $("#photos").html(@view.render().el)
+
+  index: ->
+    @view = new Cake.Views.Photos.IndexView(photos: @photos)
+    $("#photos").html(@view.render().el)
+
+  show: (id) ->
+    photo = @photos.get(id)
+
+    @view = new Cake.Views.Photos.ShowView(model: photo)
+    $("#photos").html(@view.render().el)
+
+  edit: (id) ->
+    photo = @photos.get(id)
+
+    @view = new Cake.Views.Photos.EditView(model: photo)
+    $("#photos").html(@view.render().el)
app/assets/javascripts/backbone/templates/cakes/cake.jst.ejs
@@ -1,7 +1,7 @@
 <div class="span4">
   <div class="thumbnail">
     <a href="#/<%= id %>">
-      <img src="" />
+      <img src="<%= photos[0].large_url %>" />
     </a>
     <div class="caption">
       <h3><a href="#/<%= id %>"><%= name %></a></h3>
app/assets/javascripts/backbone/templates/cakes/show.jst.ejs
@@ -1,13 +1,36 @@
-<a href="#/index">Back</a>
+<a href="#/">Back</a>
 
 <div class="row">
   <div class="span6">
-    <img class="thumbnail" src="large_image_url" alt="<%= name %>" />
+    <img class="thumbnail" src="<%= photos[0].large_url %>" alt="<%= name %>" />
   </div>
   <div class="span6">
-    <h1><a href="#/show/<%= id %>"><%= name %></a></h1>
-    <p>By <a href="#">username</a></p>
+    <h1><a href="#/<%= id %>"><%= name %></a></h1>
+    <p>By <a href="<%= Routes.profile_path(user.id) %>"><%= user.name %></a></p>
+    <span> <i class="icon-tags"></i> </span>
+    <% _.each(tags, function(tag){ %>
+      <a href="<%= Routes.creation_tag_path(tag.name) %>">
+        <span class="label"><%= tag.name %></span>
+      </a>
+    <% }); %>
     <hr />
     <p><%= story %></p>
   </div>
 </div>
+
+<div class="row">
+  <div class="span12">
+    <a href="<%= Routes.creation_photos_path(id) %>">View photos &raquo;</a>
+  </div>
+  <div class="span12">
+    <ul class="thumbnails">
+    <% _.each(photos, function(photo) { %>
+      <li class="span2">
+      <a href="<%= Routes.creation_photo_path(id, photo.id) %>">
+        <img src="<%= photo.thumb_url %>" class="thumbnail" />
+      </a>
+      </li>
+    <% }); %>
+    </ul>
+  </div>
+</div>
app/assets/javascripts/backbone/templates/photos/edit.jst.ejs
@@ -0,0 +1,20 @@
+<h1>Edit photo</h1>
+
+<form id="edit-photo" name="photo">
+  <div class="field">
+    <label for="thumb_url"> thumb_url:</label>
+    <input type="text" name="thumb_url" id="thumb_url" value="<%= thumb_url %>" >
+  </div>
+
+  <div class="field">
+    <label for="large_url"> large_url:</label>
+    <input type="text" name="large_url" id="large_url" value="<%= large_url %>" >
+  </div>
+
+  <div class="actions">
+    <input type="submit" value="Update Photo" />
+  </div>
+
+</form>
+
+<a href="#/index">Back</a>
\ No newline at end of file
app/assets/javascripts/backbone/templates/photos/index.jst.ejs
@@ -0,0 +1,15 @@
+<h1>Listing photos</h1>
+
+<table id="photos-table">
+  <tr>
+    <th>Thumb url</th>
+    <th>Large url</th>
+    <th></th>
+    <th></th>
+    <th></th>
+  </tr>
+</table>
+
+<br/>
+
+<a href="#/new">New Photo</a>
\ No newline at end of file
app/assets/javascripts/backbone/templates/photos/new.jst.ejs
@@ -0,0 +1,20 @@
+<h1>New photo</h1>
+
+<form id="new-photo" name="photo">
+  <div class="field">
+    <label for="thumb_url"> thumb_url:</label>
+    <input type="text" name="thumb_url" id="thumb_url" value="<%= thumb_url %>" >
+  </div>
+
+  <div class="field">
+    <label for="large_url"> large_url:</label>
+    <input type="text" name="large_url" id="large_url" value="<%= large_url %>" >
+  </div>
+
+  <div class="actions">
+    <input type="submit" value="Create Photo" />
+  </div>
+
+</form>
+
+<a href="#/index">Back</a>
\ No newline at end of file
app/assets/javascripts/backbone/templates/photos/photo.jst.ejs
@@ -0,0 +1,6 @@
+<td><%= thumb_url %></td>
+<td><%= large_url %></td>
+
+<td><a href="#/<%= id %>">Show</td>
+<td><a href="#/<%= id %>/edit">Edit</td>
+<td><a href="#/<%= id %>/destroy" class="destroy">Destroy</a></td>
\ No newline at end of file
app/assets/javascripts/backbone/templates/photos/show.jst.ejs
@@ -0,0 +1,12 @@
+<p>
+  <b>Thumb url:</b>
+  <%= thumb_url %>
+</p>
+
+<p>
+  <b>Large url:</b>
+  <%= large_url %>
+</p>
+
+
+<a href="#/index">Back</a>
\ No newline at end of file
app/assets/javascripts/backbone/views/cakes/show_view.js.coffee
@@ -4,5 +4,5 @@ class Cake.Views.Cakes.ShowView extends Backbone.View
   template: JST["backbone/templates/cakes/show"]
 
   render: ->
-    $(@el).html(@template(@model.toJSON() ))
+    $(@el).html(@template(@model.toJSON()))
     return this
app/assets/javascripts/backbone/views/photos/edit_view.js.coffee
@@ -0,0 +1,24 @@
+Cake.Views.Photos ||= {}
+
+class Cake.Views.Photos.EditView extends Backbone.View
+  template : JST["backbone/templates/photos/edit"]
+
+  events :
+    "submit #edit-photo" : "update"
+
+  update : (e) ->
+    e.preventDefault()
+    e.stopPropagation()
+
+    @model.save(null,
+      success : (photo) =>
+        @model = photo
+        window.location.hash = "/#{@model.id}"
+    )
+
+  render : ->
+    $(@el).html(@template(@model.toJSON() ))
+
+    this.$("form").backboneLink(@model)
+
+    return this
app/assets/javascripts/backbone/views/photos/index_view.js.coffee
@@ -0,0 +1,20 @@
+Cake.Views.Photos ||= {}
+
+class Cake.Views.Photos.IndexView extends Backbone.View
+  template: JST["backbone/templates/photos/index"]
+
+  initialize: () ->
+    @options.photos.bind('reset', @addAll)
+
+  addAll: () =>
+    @options.photos.each(@addOne)
+
+  addOne: (photo) =>
+    view = new Cake.Views.Photos.PhotoView({model : photo})
+    @$("tbody").append(view.render().el)
+
+  render: =>
+    $(@el).html(@template(photos: @options.photos.toJSON() ))
+    @addAll()
+
+    return this
app/assets/javascripts/backbone/views/photos/new_view.js.coffee
@@ -0,0 +1,37 @@
+Cake.Views.Photos ||= {}
+
+class Cake.Views.Photos.NewView extends Backbone.View
+  template: JST["backbone/templates/photos/new"]
+
+  events:
+    "submit #new-photo": "save"
+
+  constructor: (options) ->
+    super(options)
+    @model = new @collection.model()
+
+    @model.bind("change:errors", () =>
+      this.render()
+    )
+
+  save: (e) ->
+    e.preventDefault()
+    e.stopPropagation()
+
+    @model.unset("errors")
+
+    @collection.create(@model.toJSON(),
+      success: (photo) =>
+        @model = photo
+        window.location.hash = "/#{@model.id}"
+
+      error: (photo, jqXHR) =>
+        @model.set({errors: $.parseJSON(jqXHR.responseText)})
+    )
+
+  render: ->
+    $(@el).html(@template(@model.toJSON() ))
+
+    this.$("form").backboneLink(@model)
+
+    return this
app/assets/javascripts/backbone/views/photos/photo_view.js.coffee
@@ -0,0 +1,19 @@
+Cake.Views.Photos ||= {}
+
+class Cake.Views.Photos.PhotoView extends Backbone.View
+  template: JST["backbone/templates/photos/photo"]
+
+  events:
+    "click .destroy" : "destroy"
+
+  tagName: "tr"
+
+  destroy: () ->
+    @model.destroy()
+    this.remove()
+
+    return false
+
+  render: ->
+    $(@el).html(@template(@model.toJSON() ))
+    return this
app/assets/javascripts/backbone/views/photos/show_view.js.coffee
@@ -0,0 +1,8 @@
+Cake.Views.Photos ||= {}
+
+class Cake.Views.Photos.ShowView extends Backbone.View
+  template: JST["backbone/templates/photos/show"]
+
+  render: ->
+    $(@el).html(@template(@model.toJSON() ))
+    return this
app/assets/javascripts/backbone/cake.js.coffee
@@ -10,5 +10,7 @@ window.Cake =
   Routers: {}
   Views: {}
   initialize: (data) ->
-    new Cake.Routers.CakesRouter({ cakes: data.cakes })
-    Backbone.history.start()
+    $(document).ajaxSend  (event, xhr) ->
+      if data.access_token
+        xhr.setRequestHeader "Authorization", "Token token=" + data.access_token
+    new Cake.Routers.CakesRouter()
app/controllers/api/v1/api_controller.rb
@@ -0,0 +1,16 @@
+module Api
+  module V1
+    class ApiController < ApplicationController
+      before_filter :restrict_access
+      attr_reader :current_user
+
+      private
+
+      def restrict_access
+        authenticate_or_request_with_http_token do |token, options|
+          @current_user = User.find_by(authentication_token: token)
+        end
+      end
+    end
+  end
+end
app/controllers/api/v1/cakes_controller.rb
@@ -0,0 +1,15 @@
+module Api
+  module V1
+    class CakesController < ApiController
+      respond_to :json
+
+      def index
+        respond_with(@cakes = current_user.creations)
+      end
+
+      def show
+        respond_with(@cake = current_user.creations.find(params[:id]))
+      end
+    end
+  end
+end
app/controllers/api/v1/creations_controller.rb
@@ -1,25 +0,0 @@
-module Api
-  module V1
-    class CreationsController < ApplicationController
-      before_filter :restrict_access
-      respond_to :json
-
-      def initialize(repository = CreationRepository.new)
-        @repository = repository
-        super()
-      end
-
-      def index
-        @creations = @repository.visible_creations
-      end
-
-      private
-
-      def restrict_access
-        authenticate_or_request_with_http_token do |token, options|
-          User.exists?(:authentication_token => token)
-        end
-      end
-    end
-  end
-end
app/controllers/api/v1/photos_controller.rb
@@ -0,0 +1,7 @@
+module Api
+  module V1
+    class PhotosController < ApiController
+      respond_to :json
+    end
+  end
+end
app/controllers/cakes_controller.rb
@@ -1,7 +1,7 @@
 class CakesController < ApplicationController
-  respond_to :html, :json
+  before_filter :authenticate_user!
 
   def index
-    respond_with(@cakes = Creation.all.limit(10))
+    @cakes = current_user.creations
   end
 end
app/controllers/photos_controller.rb
@@ -1,4 +1,6 @@
 class PhotosController < ApplicationController
+  before_filter :authenticate_user!
+
   def index
     @creation = Creation.find(params[:creation_id])
     @photos = @creation.photos
app/services/application/find_all_creations_query.rb
@@ -9,3 +9,4 @@ class FindAllCreationsQuery
     @repository.visible_creations.page(params[:page]).per(params[:per_page] || DEFAULT_PER_PAGE)
   end
 end
+
app/views/api/v1/cakes/_cake.json.jbuilder
@@ -0,0 +1,23 @@
+json.id cake.id
+json.name cake.name
+json.story cake.story
+json.category do
+  json.id cake.category.id
+  json.name cake.category.name
+end
+json.user do
+  json.id cake.user.id
+  json.name cake.user.name
+end
+json.created_at cake.created_at
+json.updated_at cake.updated_at
+json.photos cake.photos do |photo|
+  json.id photo.id
+  json.large_url "https:#{photo.url_for(:large)}"
+  json.thumb_url "https:#{photo.url_for(:thumb)}"
+  json.created_at photo.created_at
+  json.updated_at photo.updated_at
+end
+json.tags cake.tags do |tag|
+  json.name tag.name
+end
app/views/api/v1/cakes/index.json.jbuilder
@@ -0,0 +1,3 @@
+json.array! @cakes do |cake|
+  json.partial! 'cake', cake: cake
+end
app/views/api/v1/cakes/show.json.jbuilder
@@ -0,0 +1,1 @@
+json.partial! 'cake', cake: @cake
app/views/api/v1/creations/index.json.jbuilder
@@ -1,11 +0,0 @@
-json.array! @creations do |creation|
-  json.id creation.id
-  json.name creation.name
-  json.user do
-    json.name creation.user.name
-  end
-  json.photo "http:#{creation.photos.first.image.thumb.url}"
-  json.photos creation.photos do |photo|
-    json.url "http:#{photo.image.thumb.url}"
-  end
-end
app/views/cakes/index.html.erb
@@ -1,8 +1,7 @@
 <%= content_for :javascript do -%>
   <%= javascript_tag do %>
-    Cake.initialize({ cakes: <%== @cakes.to_json %> });
+    Cake.initialize({ access_token: '<%= current_user.authentication_token %>' });
   <% end %>
 <% end -%>
 
-<div id="cakes">
-</div>
+<div id="cakes"></div>
config/routes.rb
@@ -46,7 +46,9 @@ Cake::Application.routes.draw do
 
   namespace :api, :defaults => { :format => 'json' }  do
     namespace :v1 do
-      resources :creations, :only => [:index]
+      resources :cakes, :only => [:index, :show] do
+        resources :photos, :only => [:index]
+      end
       resources :logins, :only => [:create]
     end
   end