Commit 33bce064
Changed files (31)
app
assets
javascripts
backbone
models
templates
views
controllers
services
application
views
api
v1
creations
cakes
config
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 »</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