From ee38d3393a2a01eba379a80feb336bf5c20001a8 Mon Sep 17 00:00:00 2001 From: andrew Date: Fri, 1 Feb 2008 07:43:40 +0000 Subject: [PATCH] adding friends git-svn-id: http://svn.barleysodas.com/barleysodas/trunk@116 0f7b21a7-9e3a-4941-bbeb-ce5c7c368fa7 --- app/controllers/friends_controller.rb | 49 ++++++++++++++++++ app/helpers/friends_helper.rb | 3 ++ app/helpers/peoples_helper.rb | 17 ++++++ app/models/friend.rb | 16 ++++++ app/models/people.rb | 10 ++++ app/views/friends/show.rhtml | 7 +++ app/views/peoples/show.rhtml | 3 ++ config/routes.rb | 4 +- db/migrate/013_create_friends.rb | 16 ++++++ generate_permissions | 7 ++- public/images/list-add.png | Bin 0 -> 323 bytes public/images/list-remove.png | Bin 0 -> 247 bytes public/stylesheets/content.css | 2 +- test/fixtures/friends.yml | 5 ++ test/functional/friends_controller_test.rb | 57 +++++++++++++++++++++ test/unit/friend_test.rb | 10 ++++ 16 files changed, 201 insertions(+), 5 deletions(-) create mode 100644 app/controllers/friends_controller.rb create mode 100644 app/helpers/friends_helper.rb create mode 100644 app/models/friend.rb create mode 100644 app/views/friends/show.rhtml create mode 100644 db/migrate/013_create_friends.rb create mode 100644 public/images/list-add.png create mode 100644 public/images/list-remove.png create mode 100644 test/fixtures/friends.yml create mode 100644 test/functional/friends_controller_test.rb create mode 100644 test/unit/friend_test.rb diff --git a/app/controllers/friends_controller.rb b/app/controllers/friends_controller.rb new file mode 100644 index 0000000..11cdd02 --- /dev/null +++ b/app/controllers/friends_controller.rb @@ -0,0 +1,49 @@ +class FriendsController < ApplicationController + append_before_filter :fetch_people, :only => [ :show, :destroy ] + + # GET /friends/1 + # GET /friends/1.xml + def show + @content_title = "Friends of #{@people.title}" + @friends = @people.actual_friends + respond_to do |format| + format.html # show.rhtml + format.xml { render :xml => @friends.to_xml } + end + end + + # POST /friends + # POST /friends.xml + def create + @friend = Friend.new(params[:friend]) + respond_to do |format| + if @friend.save + flash[:notice] = 'Successfully added the new friend' + format.html { redirect_to people_path(@people.page.title_for_url) } + else + format.html { render :action => "new" } + end + end + end + + # DELETE /friends/1 + # DELETE /friends/1.xml + def destroy + @friend = Friend.find :first, + :conditions => [ 'source_id = ? AND destination_id = ?', + params[:d].to_i, @people.id ] + @friend.destroy if @friend + respond_to do |format| + flash[:notice] = 'Removed the friend' + format.html { redirect_to people_path(@people.page.title_for_url) } + end + end + + protected + + def fetch_people + @people = People.find_by_title(Page.title_from_url(params[:id])) + raise ActiveRecord::RecordNotFound.new if @people.nil? + @page = @people.page + end +end diff --git a/app/helpers/friends_helper.rb b/app/helpers/friends_helper.rb new file mode 100644 index 0000000..24d631f --- /dev/null +++ b/app/helpers/friends_helper.rb @@ -0,0 +1,3 @@ +module FriendsHelper + include PeoplesHelper +end diff --git a/app/helpers/peoples_helper.rb b/app/helpers/peoples_helper.rb index 574fe22..dfcf705 100644 --- a/app/helpers/peoples_helper.rb +++ b/app/helpers/peoples_helper.rb @@ -12,4 +12,21 @@ module PeoplesHelper link_to 'Edit People', edit_people_path(people.page.title_for_url), { :title => "Edit #{people.title}" } end + + def show_friends_link(people) + link_to "#{people.title}'s Friends (#{people.actual_friends.size})", + friend_path(people.page.title_for_url) + end + + def add_friend_link(people) + link_to "#{image_tag('list-add.png')} Friend", + friends_path('friend[source_id]' => session[:people_id], + 'friend[destination_id]' => people.id), :method => :post + end + + def remove_friend_link(people) + link_to "#{image_tag('list-remove.png')} Friend", + friend_url(:id => people.page.title_for_url, :d => session[:people_id]), + :method => :delete + end end diff --git a/app/models/friend.rb b/app/models/friend.rb new file mode 100644 index 0000000..7b7788b --- /dev/null +++ b/app/models/friend.rb @@ -0,0 +1,16 @@ +## +# Represents a relationship of association between two People models. +# +class Friend < ActiveRecord::Base + belongs_to :source, :class_name => 'People', :foreign_key => :source_id + belongs_to :destination, :class_name => 'People', + :foreign_key => :destination_id + validates_presence_of :source_id, :destination_id + validates_uniqueness_of :destination_id, :scope => :source_id + + validates_each :destination_id do |record, attr, value| + if value == record.source_id + record.errors.add(attr, 'cannot be the same as the source') + end + end +end diff --git a/app/models/people.rb b/app/models/people.rb index 4069f8f..e3111b1 100644 --- a/app/models/people.rb +++ b/app/models/people.rb @@ -10,11 +10,21 @@ class People < ActiveRecord::Base has_many :images, :dependent => :destroy has_many_tagged_images validates_uniqueness_of :title + has_many :friends, :foreign_key => :source_id, :dependent => :destroy + has_many :actual_friends, :through => :friends, :source => :destination make_authenticatable validates_length_of :password, :minimum => 8, :if => :password_required?, :message => 'must be at least 8 characters in length' + ## + # Used to quickly determine if the particular id of another Person is a + # Friend of this instance. + # + def friend_of?(people_id) + Friend.count([ 'source_id = ? AND destination_id = ?', people_id, id ]) > 0 + end + ## # Finds me. # diff --git a/app/views/friends/show.rhtml b/app/views/friends/show.rhtml new file mode 100644 index 0000000..2235dc4 --- /dev/null +++ b/app/views/friends/show.rhtml @@ -0,0 +1,7 @@ +<% for friend in @friends do -%> +
<%= link_to friend.title, people_path(friend.page.title_for_url) -%>
+<% end -%> + +<% content_for :sidebar do -%> + <%= show_people_link(@people) -%>
+<% end -%> \ No newline at end of file diff --git a/app/views/peoples/show.rhtml b/app/views/peoples/show.rhtml index bd48ad3..9e491eb 100644 --- a/app/views/peoples/show.rhtml +++ b/app/views/peoples/show.rhtml @@ -7,4 +7,7 @@ <%= edit_people_link(@people) %>
<%= link_to 'Destroy', people_path(@people.page.title_for_url), :confirm => 'Are you sure?', :method => :delete %>
<% unless @people.tagged_images.empty? -%><%= tagged_image_browser_link -%>
<% end -%> + <%= show_friends_link(@people) -%>
+ <% unless @people.id == session[:people_id] or @people.friend_of?(session[:people_id]) -%><%= add_friend_link(@people) -%><% end -%> + <% if @people.friend_of?(session[:people_id]) -%><%= remove_friend_link(@people) -%><% end -%> <% end -%> \ No newline at end of file diff --git a/config/routes.rb b/config/routes.rb index fe9a874..4b94a67 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,8 +1,6 @@ ActionController::Routing::Routes.draw do |map| - map.resources :tag_images - map.resources :beers, :breweries, :pages, :discussions, :peoples, :roles, - :sessions, :styles, :galleries, :tag_images + :sessions, :styles, :galleries, :tag_images, :friends map.connect ':controller/:action/:id.:format' map.connect ':controller/:action/:id' diff --git a/db/migrate/013_create_friends.rb b/db/migrate/013_create_friends.rb new file mode 100644 index 0000000..8ef38e6 --- /dev/null +++ b/db/migrate/013_create_friends.rb @@ -0,0 +1,16 @@ +class CreateFriends < ActiveRecord::Migration + def self.up + create_table :friends do |t| + t.column :source_id, :integer + t.column :destination_id, :integer + t.column :rank, :integer + t.column :created_at, :timestamp + end + add_index :friends, :source_id + add_index :friends, :destination_id + end + + def self.down + drop_table :friends + end +end diff --git a/generate_permissions b/generate_permissions index d2ccdd8..ef031ae 100644 --- a/generate_permissions +++ b/generate_permissions @@ -5,7 +5,7 @@ base_actions = ApplicationController.action_methods # rather than defining them here. controllers = [ PagesController, DiscussionsController, StylesController, PeoplesController, BeersController, BreweriesController, RolesController, - GalleriesController, TagImagesController ] + GalleriesController, TagImagesController, FriendsController ] controllers.each do |c| actions = c.action_methods - base_actions cname = c.controller_name @@ -33,6 +33,11 @@ Permission.find(:all, next if [ 'show', 'create', 'destroy', 'taggable_search' ].include?(p.action) r.permissions << p end +Permission.find(:all, + :conditions => [ 'controller = ?', 'friends' ]).each do |p| + next if [ 'edit', 'create', 'destroy' ].include?(p.action) + r.permissions << p +end r2 = Role.admin_role Permission.find(:all).each do |p| diff --git a/public/images/list-add.png b/public/images/list-add.png new file mode 100644 index 0000000000000000000000000000000000000000..1aa7f095c6c282262390748ab2e596a3fc15c228 GIT binary patch literal 323 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Y)RhkE7hmi)!cT|6FkAON{jSt(_u!Lq7!B=^4B;IBq%dL`6}O%gpGjO3}J1 z4Y?KfzQ;%l3Rp(0FF*F|EI&io>j^)N99Xu9ZE@HjcqrgTrepSr)S!;v7$d z7#j|r*sm7k|1`qSzwL6X$#3JGkN$s>{Cx9Ec6v|es;&OpMC)hUh7@^ocW)~11Nx1@ M)78&qol`;+0M{XYA^-pY literal 0 HcmV?d00001 diff --git a/public/images/list-remove.png b/public/images/list-remove.png new file mode 100644 index 0000000000000000000000000000000000000000..00b654e8ca567c380fa477d4b32f808c3b5500d3 GIT binary patch literal 247 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Y)RhkEZLFV~EA+w-YyVHU|i_?Pt%tbHGab z1&5^a+FUmdNd@kXwZ%tROFFJ>Q*!zI&R_A==FP^f@-i~)|I20A*?&KNrgrv}l!w`~ zS-W;DV_2Rr!zN$cO_)z&Zy0B$7WFVdQ&MBb@09MjczW@LL literal 0 HcmV?d00001 diff --git a/public/stylesheets/content.css b/public/stylesheets/content.css index e2cbdbe..61498ce 100644 --- a/public/stylesheets/content.css +++ b/public/stylesheets/content.css @@ -256,7 +256,7 @@ } /* People uploaded Image styling */ -#content .people_image { +#content .people_image, #content .friend_box { border: 1px solid #DDD; background-color: #F2F2F2; float: left; diff --git a/test/fixtures/friends.yml b/test/fixtures/friends.yml new file mode 100644 index 0000000..b49c4eb --- /dev/null +++ b/test/fixtures/friends.yml @@ -0,0 +1,5 @@ +# Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html +one: + id: 1 +two: + id: 2 diff --git a/test/functional/friends_controller_test.rb b/test/functional/friends_controller_test.rb new file mode 100644 index 0000000..d6ffd05 --- /dev/null +++ b/test/functional/friends_controller_test.rb @@ -0,0 +1,57 @@ +require File.dirname(__FILE__) + '/../test_helper' +require 'friends_controller' + +# Re-raise errors caught by the controller. +class FriendsController; def rescue_action(e) raise e end; end + +class FriendsControllerTest < Test::Unit::TestCase + fixtures :friends + + def setup + @controller = FriendsController.new + @request = ActionController::TestRequest.new + @response = ActionController::TestResponse.new + end + + def test_should_get_index + get :index + assert_response :success + assert assigns(:friends) + end + + def test_should_get_new + get :new + assert_response :success + end + + def test_should_create_friend + old_count = Friend.count + post :create, :friend => { } + assert_equal old_count+1, Friend.count + + assert_redirected_to friend_path(assigns(:friend)) + end + + def test_should_show_friend + get :show, :id => 1 + assert_response :success + end + + def test_should_get_edit + get :edit, :id => 1 + assert_response :success + end + + def test_should_update_friend + put :update, :id => 1, :friend => { } + assert_redirected_to friend_path(assigns(:friend)) + end + + def test_should_destroy_friend + old_count = Friend.count + delete :destroy, :id => 1 + assert_equal old_count-1, Friend.count + + assert_redirected_to friends_path + end +end diff --git a/test/unit/friend_test.rb b/test/unit/friend_test.rb new file mode 100644 index 0000000..456810c --- /dev/null +++ b/test/unit/friend_test.rb @@ -0,0 +1,10 @@ +require File.dirname(__FILE__) + '/../test_helper' + +class FriendTest < Test::Unit::TestCase + fixtures :friends + + # Replace this with your real tests. + def test_truth + assert true + end +end