Commit 9c089f2c

mo k <m@mokhan.ca>
2012-01-06 04:20:50
start adding likes.
1 parent 930e496
app/assets/javascripts/likes.js.coffee
@@ -0,0 +1,3 @@
+# Place all the behaviors and hooks related to the matching controller here.
+# All this logic will automatically be available in application.js.
+# You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/
app/assets/stylesheets/likes.css.scss
@@ -0,0 +1,3 @@
+// Place all the styles related to the Likes controller here.
+// They will automatically be included in application.css.
+// You can use Sass (SCSS) here: http://sass-lang.com/
app/assets/stylesheets/scaffolds.css.scss
@@ -0,0 +1,56 @@
+body {
+  background-color: #fff;
+  color: #333;
+  font-family: verdana, arial, helvetica, sans-serif;
+  font-size: 13px;
+  line-height: 18px; }
+
+p, ol, ul, td {
+  font-family: verdana, arial, helvetica, sans-serif;
+  font-size: 13px;
+  line-height: 18px; }
+
+pre {
+  background-color: #eee;
+  padding: 10px;
+  font-size: 11px; }
+
+a {
+  color: #000;
+  &:visited {
+    color: #666; }
+  &:hover {
+    color: #fff;
+    background-color: #000; } }
+
+div {
+  &.field, &.actions {
+    margin-bottom: 10px; } }
+
+#notice {
+  color: green; }
+
+.field_with_errors {
+  padding: 2px;
+  background-color: red;
+  display: table; }
+
+#error_explanation {
+  width: 450px;
+  border: 2px solid red;
+  padding: 7px;
+  padding-bottom: 0;
+  margin-bottom: 20px;
+  background-color: #f0f0f0;
+  h2 {
+    text-align: left;
+    font-weight: bold;
+    padding: 5px 5px 5px 15px;
+    font-size: 12px;
+    margin: -7px;
+    margin-bottom: 0px;
+    background-color: #c00;
+    color: #fff; }
+  ul li {
+    font-size: 12px;
+    list-style: square; } }
app/controllers/likes_controller.rb
@@ -0,0 +1,98 @@
+class LikesController < ApplicationController
+  before_filter :authenticate_user!
+  before_filter :find_creation
+  # GET /likes
+  # GET /likes.json
+  def index
+    # @likes = Like.all
+    @likes = @creation.likes
+
+    respond_to do |format|
+      format.html # index.html.erb
+      format.json { render json: @likes }
+    end
+  end
+
+  # GET /likes/1
+  # GET /likes/1.json
+  def show
+    # @like = Like.find(params[:id])
+    @like = @creation.likes.find(params[:id])
+
+    respond_to do |format|
+      format.html # show.html.erb
+      format.json { render json: @like }
+    end
+  end
+
+  # GET /likes/new
+  # GET /likes/new.json
+  def new
+    @like = Like.new
+
+    respond_to do |format|
+      format.html # new.html.erb
+      format.json { render json: @like }
+    end
+  end
+
+  # GET /likes/1/edit
+  def edit
+    @like = @creation.likes.find(params[:id])
+    # @like = Like.find(params[:id])
+  end
+
+  # POST /likes
+  # POST /likes.json
+  def create
+    # @like = Like.new(params[:like])
+    @like = @creation.likes.create(params[:like])
+    @like.user_id = current_user.id
+
+    respond_to do |format|
+      if @like.save
+        format.html { redirect_to @creation, notice: 'Like was successfully created.' }
+        format.json { render json: @like, status: :created, location: @like }
+      else
+        format.html { render action: "new" }
+        format.json { render json: @like.errors, status: :unprocessable_entity }
+      end
+    end
+  end
+
+  # PUT /likes/1
+  # PUT /likes/1.json
+  def update
+    # @like = Like.find(params[:id])
+    @like = @creations.likes.find(params[:id])
+
+    respond_to do |format|
+      if @like.update_attributes(params[:like])
+        format.html { redirect_to @like, notice: 'Like was successfully updated.' }
+        format.json { head :ok }
+      else
+        format.html { render action: "edit" }
+        format.json { render json: @like.errors, status: :unprocessable_entity }
+      end
+    end
+  end
+
+  # DELETE /likes/1
+  # DELETE /likes/1.json
+  def destroy
+    # @like = Like.find(params[:id])
+    @like = @creation.likes.find(params[:id])
+    @like.destroy
+
+    respond_to do |format|
+      format.html { redirect_to likes_url }
+      format.json { head :ok }
+    end
+  end
+
+  private
+  def find_creation
+    @creation = current_user.creations.find(params[:creation_id])
+    raise ActiveRecord::RecordNotFound unless @creation
+  end
+end
app/helpers/likes_helper.rb
@@ -0,0 +1,2 @@
+module LikesHelper
+end
app/models/creation.rb
@@ -5,6 +5,7 @@ class Creation < ActiveRecord::Base
   belongs_to :user
   has_and_belongs_to_many :categories, :join_table => 'creations_categories', :uniq => true, :autosave => true
   has_many :photos, :dependent => :destroy
+  has_many :likes, :dependent => :destroy
   mount_uploader :image, ImageUploader
 
   attr_accessor :crop_x, :crop_y, :crop_h, :crop_w
app/models/like.rb
@@ -0,0 +1,4 @@
+class Like < ActiveRecord::Base
+  belongs_to :user
+  belongs_to :creation
+end
app/models/user.rb
@@ -9,6 +9,7 @@ class User < ActiveRecord::Base
   attr_accessible :name, :email, :password, :password_confirmation, :remember_me
 
   has_many :creations, :dependent => :destroy
+  has_many :likes, :dependent => :destroy
 
   def apply_omniauth(omniauth)
     puts omniauth
app/views/creations/show.html.erb
@@ -31,6 +31,7 @@
       </div>
     </div>
   </div>
+
   <div class="span4">
     <ul class="media-grid">
       <% @creation.photos.each do |photo| %>
@@ -40,6 +41,19 @@
   </div>
 </div>
 
+<div class="row">
+  <div class="span16">
+    <%= button_to "+1", creation_likes_path(:creation_id => @creation.id), :method => :post %>
+    <%= pluralize(@creation.likes.length, 'like') %>
+    <h3>artists who like this creation</h3>
+    <ul class="media-grid">
+    <% @creation.likes.each do |like| %>
+        <a href="<%= url_for profile_path(like.user) %>"><img src="<%= avatar_url like.user %>&amp;s=200" alt="<%= like.user.name %>" /></a>
+    <% end %>
+    </ul>
+  </div>
+</div>
+
 <div class="row">
   <div class="span16">
     <h3>Description</h3>
app/views/likes/_form.html.erb
@@ -0,0 +1,25 @@
+<%= form_for([@creation, @like]) do |f| %>
+  <% if @like.errors.any? %>
+    <div id="error_explanation">
+      <h2><%= pluralize(@like.errors.count, "error") %> prohibited this like from being saved:</h2>
+
+      <ul>
+      <% @like.errors.full_messages.each do |msg| %>
+        <li><%= msg %></li>
+      <% end %>
+      </ul>
+    </div>
+  <% end %>
+
+  <div class="field">
+    <%= f.label :user_id %><br />
+    <%= f.number_field :user_id %>
+  </div>
+  <div class="field">
+    <%= f.label :creation_id %><br />
+    <%= f.number_field :creation_id %>
+  </div>
+  <div class="actions">
+    <%= f.submit %>
+  </div>
+<% end %>
app/views/likes/edit.html.erb
@@ -0,0 +1,6 @@
+<h1>Editing like</h1>
+
+<%= render 'form' %>
+
+<%= link_to 'Show', @like %> |
+<%= link_to 'Back', creation_likes_path %>
app/views/likes/index.html.erb
@@ -0,0 +1,25 @@
+<h1>Listing likes</h1>
+
+<table>
+  <tr>
+    <th>User</th>
+    <th>Creation</th>
+    <th></th>
+    <th></th>
+    <th></th>
+  </tr>
+
+<% @likes.each do |like| %>
+  <tr>
+    <td><%= like.user_id %></td>
+    <td><%= like.creation_id %></td>
+    <td><%= link_to 'Show', creation_like_path(like) %></td>
+    <td><%= link_to 'Edit', edit_creation_like_path(like) %></td>
+    <%# <td><%= link_to 'Destroy', like, confirm: 'Are you sure?', method: :delete %></td>%>
+  </tr>
+<% end %>
+</table>
+
+<br />
+
+<%= link_to 'New Like', new_creation_like_path %>
app/views/likes/new.html.erb
@@ -0,0 +1,5 @@
+<h1>New like</h1>
+
+<%= render 'form' %>
+
+<%= link_to 'Back', creation_likes_path %>
app/views/likes/show.html.erb
@@ -0,0 +1,15 @@
+<p id="notice"><%= notice %></p>
+
+<p>
+  <b>User:</b>
+  <%= @like.user_id %>
+</p>
+
+<p>
+  <b>Creation:</b>
+  <%= @like.creation_id %>
+</p>
+
+
+<%= link_to 'Edit', edit_creation_like_path(@like) %> |
+<%= link_to 'Back', creation_likes_path %>
config/routes.rb
@@ -1,4 +1,5 @@
 Cake::Application.routes.draw do
+
   root :to => "home#index"
 
   # /home
@@ -7,6 +8,7 @@ Cake::Application.routes.draw do
   # /creations
   resources :creations do
     resources :photos, :only => [:create, :destroy]
+    resources :likes
   end
   match 'creations/crop/:id' => 'creations#crop', :method => 'GET'
   match 'creations/crop_update/:id' => 'creations#crop_update', :as => 'creations_crop_update', :method => 'POST'
db/migrate/20120106021715_create_likes.rb
@@ -0,0 +1,10 @@
+class CreateLikes < ActiveRecord::Migration
+  def change
+    create_table :likes do |t|
+      t.integer :user_id
+      t.integer :creation_id
+
+      t.timestamps
+    end
+  end
+end
db/schema.rb
@@ -11,7 +11,7 @@
 #
 # It's strongly recommended to check this file into your version control system.
 
-ActiveRecord::Schema.define(:version => 20111216042304) do
+ActiveRecord::Schema.define(:version => 20120106021715) do
 
   create_table "categories", :force => true do |t|
     t.string   "name"
@@ -34,6 +34,13 @@ ActiveRecord::Schema.define(:version => 20111216042304) do
     t.integer "category_id"
   end
 
+  create_table "likes", :force => true do |t|
+    t.integer  "user_id"
+    t.integer  "creation_id"
+    t.datetime "created_at"
+    t.datetime "updated_at"
+  end
+
   create_table "photos", :force => true do |t|
     t.integer  "creation_id"
     t.string   "image"
spec/controllers/likes_controller_spec.rb
@@ -0,0 +1,157 @@
+require 'spec_helper'
+
+# This spec was generated by rspec-rails when you ran the scaffold generator.
+# It demonstrates how one might use RSpec to specify the controller code that
+# was generated by Rails when you ran the scaffold generator.
+#
+# It assumes that the implementation code is generated by the rails scaffold
+# generator.  If you are using any extension libraries to generate different
+# controller code, this generated spec may or may not pass.
+#
+# It only uses APIs available in rails and/or rspec-rails.  There are a number
+# of tools you can use to make these specs even more expressive, but we're
+# sticking to rails and rspec-rails APIs to keep things simple and stable.
+#
+# Compared to earlier versions of this generator, there is very limited use of
+# stubs and message expectations in this spec.  Stubs are only used when there
+# is no simpler way to get a handle on the object needed for the example.
+# Message expectations are only used when there is no simpler way to specify
+# that an instance is receiving a specific message.
+
+describe LikesController do
+
+  # This should return the minimal set of attributes required to create a valid
+  # Like. As you add validations to Like, be sure to
+  # update the return value of this method accordingly.
+  def valid_attributes
+    {}
+  end
+
+  describe "GET index" do
+    it "assigns all likes as @likes" do
+      like = Like.create! valid_attributes
+      get :index
+      assigns(:likes).should eq([like])
+    end
+  end
+
+  describe "GET show" do
+    it "assigns the requested like as @like" do
+      like = Like.create! valid_attributes
+      get :show, :id => like.id
+      assigns(:like).should eq(like)
+    end
+  end
+
+  describe "GET new" do
+    it "assigns a new like as @like" do
+      get :new
+      assigns(:like).should be_a_new(Like)
+    end
+  end
+
+  describe "GET edit" do
+    it "assigns the requested like as @like" do
+      like = Like.create! valid_attributes
+      get :edit, :id => like.id
+      assigns(:like).should eq(like)
+    end
+  end
+
+  describe "POST create" do
+    describe "with valid params" do
+      it "creates a new Like" do
+        expect {
+          post :create, :like => valid_attributes
+        }.to change(Like, :count).by(1)
+      end
+
+      it "assigns a newly created like as @like" do
+        post :create, :like => valid_attributes
+        assigns(:like).should be_a(Like)
+        assigns(:like).should be_persisted
+      end
+
+      it "redirects to the created like" do
+        post :create, :like => valid_attributes
+        response.should redirect_to(Like.last)
+      end
+    end
+
+    describe "with invalid params" do
+      it "assigns a newly created but unsaved like as @like" do
+        # Trigger the behavior that occurs when invalid params are submitted
+        Like.any_instance.stub(:save).and_return(false)
+        post :create, :like => {}
+        assigns(:like).should be_a_new(Like)
+      end
+
+      it "re-renders the 'new' template" do
+        # Trigger the behavior that occurs when invalid params are submitted
+        Like.any_instance.stub(:save).and_return(false)
+        post :create, :like => {}
+        response.should render_template("new")
+      end
+    end
+  end
+
+  describe "PUT update" do
+    describe "with valid params" do
+      it "updates the requested like" do
+        like = Like.create! valid_attributes
+        # Assuming there are no other likes in the database, this
+        # specifies that the Like created on the previous line
+        # receives the :update_attributes message with whatever params are
+        # submitted in the request.
+        Like.any_instance.should_receive(:update_attributes).with({'these' => 'params'})
+        put :update, :id => like.id, :like => {'these' => 'params'}
+      end
+
+      it "assigns the requested like as @like" do
+        like = Like.create! valid_attributes
+        put :update, :id => like.id, :like => valid_attributes
+        assigns(:like).should eq(like)
+      end
+
+      it "redirects to the like" do
+        like = Like.create! valid_attributes
+        put :update, :id => like.id, :like => valid_attributes
+        response.should redirect_to(like)
+      end
+    end
+
+    describe "with invalid params" do
+      it "assigns the like as @like" do
+        like = Like.create! valid_attributes
+        # Trigger the behavior that occurs when invalid params are submitted
+        Like.any_instance.stub(:save).and_return(false)
+        put :update, :id => like.id, :like => {}
+        assigns(:like).should eq(like)
+      end
+
+      it "re-renders the 'edit' template" do
+        like = Like.create! valid_attributes
+        # Trigger the behavior that occurs when invalid params are submitted
+        Like.any_instance.stub(:save).and_return(false)
+        put :update, :id => like.id, :like => {}
+        response.should render_template("edit")
+      end
+    end
+  end
+
+  describe "DELETE destroy" do
+    it "destroys the requested like" do
+      like = Like.create! valid_attributes
+      expect {
+        delete :destroy, :id => like.id
+      }.to change(Like, :count).by(-1)
+    end
+
+    it "redirects to the likes list" do
+      like = Like.create! valid_attributes
+      delete :destroy, :id => like.id
+      response.should redirect_to(likes_url)
+    end
+  end
+
+end
spec/helpers/likes_helper_spec.rb
@@ -0,0 +1,15 @@
+require 'spec_helper'
+
+# Specs in this file have access to a helper object that includes
+# the LikesHelper. For example:
+#
+# describe LikesHelper do
+#   describe "string concat" do
+#     it "concats two strings with spaces" do
+#       helper.concat_strings("this","that").should == "this that"
+#     end
+#   end
+# end
+describe LikesHelper do
+  pending "add some examples to (or delete) #{__FILE__}"
+end
spec/models/like_spec.rb
@@ -0,0 +1,5 @@
+require 'spec_helper'
+
+describe Like do
+  pending "add some examples to (or delete) #{__FILE__}"
+end
spec/requests/likes_spec.rb
@@ -0,0 +1,11 @@
+require 'spec_helper'
+
+describe "Likes" do
+  describe "GET /likes" do
+    it "works! (now write some real specs)" do
+      # Run the generator again with the --webrat flag if you want to use webrat methods/matchers
+      get likes_path
+      response.status.should be(200)
+    end
+  end
+end
spec/routing/likes_routing_spec.rb
@@ -0,0 +1,35 @@
+require "spec_helper"
+
+describe LikesController do
+  describe "routing" do
+
+    it "routes to #index" do
+      get("/likes").should route_to("likes#index")
+    end
+
+    it "routes to #new" do
+      get("/likes/new").should route_to("likes#new")
+    end
+
+    it "routes to #show" do
+      get("/likes/1").should route_to("likes#show", :id => "1")
+    end
+
+    it "routes to #edit" do
+      get("/likes/1/edit").should route_to("likes#edit", :id => "1")
+    end
+
+    it "routes to #create" do
+      post("/likes").should route_to("likes#create")
+    end
+
+    it "routes to #update" do
+      put("/likes/1").should route_to("likes#update", :id => "1")
+    end
+
+    it "routes to #destroy" do
+      delete("/likes/1").should route_to("likes#destroy", :id => "1")
+    end
+
+  end
+end
spec/views/likes/edit.html.erb_spec.rb
@@ -0,0 +1,20 @@
+require 'spec_helper'
+
+describe "likes/edit.html.erb" do
+  before(:each) do
+    @like = assign(:like, stub_model(Like,
+      :user_id => 1,
+      :creation_id => 1
+    ))
+  end
+
+  it "renders the edit like form" do
+    render
+
+    # Run the generator again with the --webrat flag if you want to use webrat matchers
+    assert_select "form", :action => likes_path(@like), :method => "post" do
+      assert_select "input#like_user_id", :name => "like[user_id]"
+      assert_select "input#like_creation_id", :name => "like[creation_id]"
+    end
+  end
+end
spec/views/likes/index.html.erb_spec.rb
@@ -0,0 +1,24 @@
+require 'spec_helper'
+
+describe "likes/index.html.erb" do
+  before(:each) do
+    assign(:likes, [
+      stub_model(Like,
+        :user_id => 1,
+        :creation_id => 1
+      ),
+      stub_model(Like,
+        :user_id => 1,
+        :creation_id => 1
+      )
+    ])
+  end
+
+  it "renders a list of likes" do
+    render
+    # Run the generator again with the --webrat flag if you want to use webrat matchers
+    assert_select "tr>td", :text => 1.to_s, :count => 2
+    # Run the generator again with the --webrat flag if you want to use webrat matchers
+    assert_select "tr>td", :text => 1.to_s, :count => 2
+  end
+end
spec/views/likes/new.html.erb_spec.rb
@@ -0,0 +1,20 @@
+require 'spec_helper'
+
+describe "likes/new.html.erb" do
+  before(:each) do
+    assign(:like, stub_model(Like,
+      :user_id => 1,
+      :creation_id => 1
+    ).as_new_record)
+  end
+
+  it "renders new like form" do
+    render
+
+    # Run the generator again with the --webrat flag if you want to use webrat matchers
+    assert_select "form", :action => likes_path, :method => "post" do
+      assert_select "input#like_user_id", :name => "like[user_id]"
+      assert_select "input#like_creation_id", :name => "like[creation_id]"
+    end
+  end
+end
spec/views/likes/show.html.erb_spec.rb
@@ -0,0 +1,18 @@
+require 'spec_helper'
+
+describe "likes/show.html.erb" do
+  before(:each) do
+    @like = assign(:like, stub_model(Like,
+      :user_id => 1,
+      :creation_id => 1
+    ))
+  end
+
+  it "renders attributes in <p>" do
+    render
+    # Run the generator again with the --webrat flag if you want to use webrat matchers
+    rendered.should match(/1/)
+    # Run the generator again with the --webrat flag if you want to use webrat matchers
+    rendered.should match(/1/)
+  end
+end