From 5350b40e3c4d27d0c78b026c3db6e2677389f9a4 Mon Sep 17 00:00:00 2001 From: maxwell Date: Wed, 7 Jul 2010 15:27:22 -0700 Subject: [PATCH 01/10] broken autotest for rafi --- app/models/comment.rb | 4 +- app/models/post.rb | 4 +- config/initializers/inflections.rb | 2 +- config/initializers/socket.rb | 39 ++++++++++----- lib/socket_render.rb | 80 +++++++++++++++--------------- spec/lib/message_handler_spec.rb | 4 +- spec/lib/socket_renderer_spec.rb | 4 +- spec/spec_helper.rb | 4 +- 8 files changed, 79 insertions(+), 62 deletions(-) diff --git a/app/models/comment.rb b/app/models/comment.rb index 98b0300fc..33d235345 100644 --- a/app/models/comment.rb +++ b/app/models/comment.rb @@ -36,6 +36,6 @@ class Comment def send_to_view - WebSocket.update_clients(self) + WebSocket.push_to_clients(self) end -end \ No newline at end of file +end diff --git a/app/models/post.rb b/app/models/post.rb index 3598dbc34..066d768a9 100644 --- a/app/models/post.rb +++ b/app/models/post.rb @@ -53,11 +53,11 @@ class Post end def send_to_view - WebSocket.update_clients(self) + WebSocket.push_to_clients(self) end def remove_from_view - WebSocket.update_clients(Retraction.for(self)) + WebSocket.push_to_clients(Retraction.for(self)) end end diff --git a/config/initializers/inflections.rb b/config/initializers/inflections.rb index dded445cc..bf760d087 100644 --- a/config/initializers/inflections.rb +++ b/config/initializers/inflections.rb @@ -7,5 +7,5 @@ # inflect.singular /^(ox)en/i, '\1' # inflect.irregular 'person', 'people' # inflect.uncountable %w( fish sheep ) - inflect.uncountable %w(dashboard) + inflect.uncountable %w(dashboard socket) end diff --git a/config/initializers/socket.rb b/config/initializers/socket.rb index 105314b8a..ac79810fd 100644 --- a/config/initializers/socket.rb +++ b/config/initializers/socket.rb @@ -1,31 +1,44 @@ require 'em-websocket' require 'eventmachine' -require 'lib/socket_render' + + + module WebSocket EM.next_tick { - EM.add_timer(0.1) do - @channel = EM::Channel.new - puts @channel.inspect - include SocketRenderer - - SocketRenderer.instantiate_view - end + initialize_channel EventMachine::WebSocket.start( :host => "0.0.0.0", :port => APP_CONFIG[:socket_port], :debug =>APP_CONFIG[:debug]) do |ws| ws.onopen { - sid = @channel.subscribe { |msg| ws.send msg } + @ws = ws + sid = SocketController.new.new_subscriber(ws) - ws.onmessage { |msg| }#@channel.push msg; puts msg} + ws.onmessage { |msg| SocketController.new.incoming(msg) }#@channel.push msg; puts msg} - ws.onclose { @channel.unsubscribe(sid) } + ws.onclose { SocketController.new.delete_subscriber(sid) } } end } - def self.update_clients(object) - @channel.push(SocketRenderer.view_hash(object).to_json) if @channel + def self.initialize_channel + @channel = EM::Channel.new + puts @channel.inspect end + + def self.push_to_clients(html) + @channel.push(html) + end + + def self.unsubscribe(sid) + @channel.unsubscribe(sid) + end + + + def self.subscribe + @channel.subscribe{ |msg| puts "hello #{msg}";@ws.send msg } + end + end + diff --git a/lib/socket_render.rb b/lib/socket_render.rb index 8d77f4c6a..6f8bcbad9 100644 --- a/lib/socket_render.rb +++ b/lib/socket_render.rb @@ -1,40 +1,40 @@ -module SocketRenderer - require 'app/helpers/application_helper' - def self.instantiate_view - @view = ActionView::Base.new(ActionController::Base.view_paths, {}) - class << @view - include ApplicationHelper - include Rails.application.routes.url_helpers - include ActionController::RequestForgeryProtection::ClassMethods - def protect_against_forgery? - false - end - end - end - - def self.view_hash(object) - begin - v = view_for(object) unless object.is_a? Retraction - - rescue Exception => e - puts "in failzord " + v.inspect - puts object.inspect - puts e.message - raise e - end - - {:class =>object.class.to_s.underscore.pluralize, :html => v, :post_id => obj_id(object)} - end - - def self.view_for(object) - @view.render @view.type_partial(object), :post => object - end - - def self.obj_id(object) - if object.is_a? Post - object.id - else - object.post_id - end - end -end +# module SocketRenderer +# require 'app/helpers/application_helper' +# def self.instantiate_view +# @view = ActionView::Base.new(ActionController::Base.view_paths, {}) +# class << @view +# include ApplicationHelper +# include Rails.application.routes.url_helpers +# include ActionController::RequestForgeryProtection::ClassMethods +# def protect_against_forgery? +# false +# end +# end +# end +# +# def self.view_hash(object) +# begin +# v = view_for(object) unless object.is_a? Retraction +# +# rescue Exception => e +# puts "in failzord " + v.inspect +# puts object.inspect +# puts e.message +# raise e +# end +# +# {:class =>object.class.to_s.underscore.pluralize, :html => v, :post_id => obj_id(object)} +# end +# +# def self.view_for(object) +# @view.render @view.type_partial(object), :post => object +# end +# +# def self.obj_id(object) +# if object.is_a? Post +# object.id +# else +# object.post_id +# end +# end +# end diff --git a/spec/lib/message_handler_spec.rb b/spec/lib/message_handler_spec.rb index 3ec0a6e2c..d2ffddb6a 100644 --- a/spec/lib/message_handler_spec.rb +++ b/spec/lib/message_handler_spec.rb @@ -105,10 +105,10 @@ describe MessageHandler do @handler.add_get_request(@message_urls) @handler.size.should == 6 @handler.process - timer = EventMachine::Timer.new(1) do + #timer = EventMachine::Timer.new(1) do @handler.size.should == 0 EventMachine.stop - end + #end } end diff --git a/spec/lib/socket_renderer_spec.rb b/spec/lib/socket_renderer_spec.rb index 19144d852..8b9cfcd6d 100644 --- a/spec/lib/socket_renderer_spec.rb +++ b/spec/lib/socket_renderer_spec.rb @@ -1,4 +1,5 @@ -require File.dirname(__FILE__) + '/../spec_helper' +=begin + require File.dirname(__FILE__) + '/../spec_helper' describe SocketRenderer do before do @@ -21,3 +22,4 @@ describe SocketRenderer do end end +=end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index a72af5197..8a8b09e50 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -24,7 +24,9 @@ RSpec.configure do |config| config.before(:each) do DatabaseCleaner.start - #WebSocket.stub!(:update_clients) + WebSocket.stub!(:push_to_clients).and_return("stub") + WebSocket.stub!(:unsubscribe).and_return("stub") + WebSocket.stub!(:subscribe).and_return("stub") end config.after(:each) do From cc603a79439dc035d2413ccc75fce0c886ec4936 Mon Sep 17 00:00:00 2001 From: maxwell Date: Wed, 7 Jul 2010 15:27:44 -0700 Subject: [PATCH 02/10] autotest for rafi --- app/controllers/socket_controller.rb | 43 ++++++++++++++++++++++ app/helpers/socket_helper.rb | 22 +++++++++++ spec/controllers/socket_controller_spec.rb | 36 ++++++++++++++++++ 3 files changed, 101 insertions(+) create mode 100644 app/controllers/socket_controller.rb create mode 100644 app/helpers/socket_helper.rb create mode 100644 spec/controllers/socket_controller_spec.rb diff --git a/app/controllers/socket_controller.rb b/app/controllers/socket_controller.rb new file mode 100644 index 000000000..65f9518a0 --- /dev/null +++ b/app/controllers/socket_controller.rb @@ -0,0 +1,43 @@ +class SocketController < ApplicationController + + def incoming(msg) + puts msg + end + + + def new_subscriber + WebSocket.subscribe + end + + + + def outgoing(object) + puts "made it sucka" + WebSocket.push_to_clients(action_hash(object)) + end + + + def delete_subscriber(sid) + WebSocket.unsubscribe(sid) + end + + +# need a data strucutre to keep track of who is where + +#the way this is set up now, we have users on pages + +#could have... a channel for every page/collection...not that cool +#or, have a single channel, which has a corresponding :current page => [sid] +# can i cherry pick subscribers from a a channel? + + +# we want all sorts of stuff that comes with being a controller +# like, protect from forgery, view rendering, etc + + +#these functions are not really routes +#so the question is, whats the best way to call them? + +#also, this is an input output controller + +end diff --git a/app/helpers/socket_helper.rb b/app/helpers/socket_helper.rb new file mode 100644 index 000000000..485b053b9 --- /dev/null +++ b/app/helpers/socket_helper.rb @@ -0,0 +1,22 @@ +module SocketHelper + + def obj_id(object) + object.is_a? Post ? object.id : object.post_id + end + + + def action_hash(object) + begin + v = render_to_string(type_partial(object), :post => object) unless object.is_a? Retraction + + rescue Exception => e + puts "in failzord " + v.inspect + puts object.inspect + puts e.message + raise e + end + + {:class =>object.class.to_s.underscore.pluralize, :html => v, :post_id => obj_id(object)} + end + +end \ No newline at end of file diff --git a/spec/controllers/socket_controller_spec.rb b/spec/controllers/socket_controller_spec.rb new file mode 100644 index 000000000..b2c8e723a --- /dev/null +++ b/spec/controllers/socket_controller_spec.rb @@ -0,0 +1,36 @@ +require File.dirname(__FILE__) + '/../spec_helper' + +describe SocketController do + before do + Factory.create(:user) + WebSocket.unstub!(:push_to_clients) + WebSocket.unstub!(:unsubscribe) + WebSocket.unstub!(:subscribe) + #EventMachine::WebSocket.stub!(:start) + @controller = SocketController.new + end + + it 'should unstub the websocket' do + EventMachine.run { + puts"hi" + WebSocket.initialize_channel + WebSocket.push_to_clients("what").should_not == "stub" + WebSocket.unsubscribe(1).should_not == "stub" + WebSocket.subscribe.should_not == "stub" + EventMachine.stop + } + puts "yo" + end + + it 'should add a new subscriber to the websocket channel' do + EventMachine.run { + puts "foo" + WebSocket.initialize_channel + @controller.new_subscriber.should == 1 + + EventMachine.stop + } + end + + +end From 2db3366ef42a795bfc364d161f43ece93239c78b Mon Sep 17 00:00:00 2001 From: Raphael Date: Wed, 7 Jul 2010 16:04:31 -0700 Subject: [PATCH 03/10] RS, MS; test FILES are now in EM run blocks, tests are in next_ticks --- spec/controllers/socket_controller_spec.rb | 14 +++--- spec/lib/message_handler_spec.rb | 51 +++++++++------------- 2 files changed, 26 insertions(+), 39 deletions(-) diff --git a/spec/controllers/socket_controller_spec.rb b/spec/controllers/socket_controller_spec.rb index b2c8e723a..483583d12 100644 --- a/spec/controllers/socket_controller_spec.rb +++ b/spec/controllers/socket_controller_spec.rb @@ -1,5 +1,5 @@ require File.dirname(__FILE__) + '/../spec_helper' - +EventMachine.run{ describe SocketController do before do Factory.create(:user) @@ -11,26 +11,22 @@ describe SocketController do end it 'should unstub the websocket' do - EventMachine.run { - puts"hi" + EventMachine.next_tick { WebSocket.initialize_channel WebSocket.push_to_clients("what").should_not == "stub" WebSocket.unsubscribe(1).should_not == "stub" WebSocket.subscribe.should_not == "stub" - EventMachine.stop } - puts "yo" end it 'should add a new subscriber to the websocket channel' do - EventMachine.run { - puts "foo" + EventMachine.next_tick { WebSocket.initialize_channel @controller.new_subscriber.should == 1 - - EventMachine.stop } end end +EventMachine.stop +} diff --git a/spec/lib/message_handler_spec.rb b/spec/lib/message_handler_spec.rb index d2ffddb6a..6c69406da 100644 --- a/spec/lib/message_handler_spec.rb +++ b/spec/lib/message_handler_spec.rb @@ -1,5 +1,6 @@ require File.dirname(__FILE__) + '/../spec_helper' +EventMachine.run{ describe MessageHandler do before do @handler = MessageHandler.new @@ -9,45 +10,42 @@ describe MessageHandler do describe 'GET messages' do describe 'creating a GET query' do + it 'should be able to add a GET query to the queue with required destinations' do - EventMachine.run{ + EM.next_tick{ @handler.add_get_request(@message_urls) @handler.size.should == @message_urls.size - EventMachine.stop - } + } end end describe 'processing a GET query' do it 'should remove sucessful http requests from the queue' do + EM.next_tick{ request = FakeHttpRequest.new(:success) request.should_receive(:get).and_return(request) EventMachine::HttpRequest.stub!(:new).and_return(request) - - EventMachine.run { @handler.add_get_request("http://www.google.com/") @handler.size.should == 1 @handler.process @handler.size.should == 0 - EventMachine.stop } end it 'should only retry a bad request three times ' do + EM.next_tick{ request = FakeHttpRequest.new(:failure) request.should_receive(:get).exactly(MessageHandler::NUM_TRIES).times.and_return(request) EventMachine::HttpRequest.stub!(:new).and_return(request) - EventMachine.run { + @handler.add_get_request("http://www.google.com/") @handler.add_get_request("http://asdfsdajfsdfbasdj.com/") @handler.size.should == 1 @handler.process @handler.size.should == 0 - - EventMachine.stop - } + } end end end @@ -56,50 +54,45 @@ describe MessageHandler do it 'should be able to add a post message to the queue' do - EventMachine.run { + EM.next_tick{ @handler.size.should ==0 @handler.add_post_request(@message_urls.first, @message_body) @handler.size.should == 1 - - EventMachine.stop - } + } end it 'should be able to insert many posts into the queue' do - EventMachine.run { + EM.next_tick{ @handler.size.should == 0 @handler.add_post_request(@message_urls, @message_body) @handler.size.should == @message_urls.size - EventMachine.stop - } + } end it 'should post a single message to a given URL' do + EM.next_tick{ request = FakeHttpRequest.new(:success) request.should_receive(:post).and_return(request) EventMachine::HttpRequest.stub!(:new).and_return(request) - EventMachine.run{ @handler.add_post_request(@message_urls.first, @message_body) @handler.size.should == 1 @handler.process @handler.size.should == 0 - - EventMachine.stop - - } + } end end describe "Mixed Queries" do it 'should process both POST and GET requests in the same queue' do + EM.next_tick{ + request = FakeHttpRequest.new(:success) request.should_receive(:get).exactly(3).times.and_return(request) request.should_receive(:post).exactly(3).times.and_return(request) EventMachine::HttpRequest.stub!(:new).and_return(request) - EventMachine.run{ @handler.add_post_request(@message_urls,@message_body) @handler.size.should == 3 @handler.add_get_request(@message_urls) @@ -107,25 +100,21 @@ describe MessageHandler do @handler.process #timer = EventMachine::Timer.new(1) do @handler.size.should == 0 - EventMachine.stop #end - } + } end it 'should be able to have seperate POST and GET have different callbacks' do + EM.next_tick{ request = FakeHttpRequest.new(:success) request.should_receive(:get).exactly(1).times.and_return(request) request.should_receive(:post).exactly(1).times.and_return(request) @handler.should_receive(:send_to_seed).once EventMachine::HttpRequest.stub!(:new).and_return(request) - - EventMachine.run{ @handler.add_post_request(@message_urls.first,@message_body) @handler.add_get_request(@message_urls.first) @handler.process - - EventMachine.stop } end @@ -136,6 +125,7 @@ class FakeHttpRequest def initialize(callback_wanted) @callback = callback_wanted end + def response "NOTE YOU ARE IN FAKE HTTP" end @@ -149,4 +139,5 @@ class FakeHttpRequest b.call if @callback == :failure end end - +EventMachine.stop +} From bf0afeede0a9fe54992820e2bf069341818cae9f Mon Sep 17 00:00:00 2001 From: maxwell Date: Wed, 7 Jul 2010 16:41:42 -0700 Subject: [PATCH 04/10] i really have no clue why this works nwow --- Gemfile | 1 + spec/controllers/socket_controller_spec.rb | 13 ++--- spec/lib/message_handler_spec.rb | 55 +++++++++++++--------- 3 files changed, 38 insertions(+), 31 deletions(-) diff --git a/Gemfile b/Gemfile index fb8243e53..d36727342 100644 --- a/Gemfile +++ b/Gemfile @@ -32,6 +32,7 @@ group :test do gem 'autotest' gem 'factory_girl_rails' gem 'database_cleaner' + gem 'em-spec', :git => 'http://github.com/danielsdeleo/em-spec.git' end group :development do diff --git a/spec/controllers/socket_controller_spec.rb b/spec/controllers/socket_controller_spec.rb index 483583d12..053175f97 100644 --- a/spec/controllers/socket_controller_spec.rb +++ b/spec/controllers/socket_controller_spec.rb @@ -1,5 +1,6 @@ require File.dirname(__FILE__) + '/../spec_helper' -EventMachine.run{ + +#require 'em-spec/rspec' describe SocketController do before do Factory.create(:user) @@ -11,22 +12,18 @@ describe SocketController do end it 'should unstub the websocket' do - EventMachine.next_tick { WebSocket.initialize_channel WebSocket.push_to_clients("what").should_not == "stub" WebSocket.unsubscribe(1).should_not == "stub" WebSocket.subscribe.should_not == "stub" - } end it 'should add a new subscriber to the websocket channel' do - EventMachine.next_tick { + + puts "balls" WebSocket.initialize_channel + puts "foobar" @controller.new_subscriber.should == 1 - } end - end -EventMachine.stop -} diff --git a/spec/lib/message_handler_spec.rb b/spec/lib/message_handler_spec.rb index 6c69406da..3ec0a6e2c 100644 --- a/spec/lib/message_handler_spec.rb +++ b/spec/lib/message_handler_spec.rb @@ -1,6 +1,5 @@ require File.dirname(__FILE__) + '/../spec_helper' -EventMachine.run{ describe MessageHandler do before do @handler = MessageHandler.new @@ -10,42 +9,45 @@ describe MessageHandler do describe 'GET messages' do describe 'creating a GET query' do - it 'should be able to add a GET query to the queue with required destinations' do - EM.next_tick{ + EventMachine.run{ @handler.add_get_request(@message_urls) @handler.size.should == @message_urls.size - } + EventMachine.stop + } end end describe 'processing a GET query' do it 'should remove sucessful http requests from the queue' do - EM.next_tick{ request = FakeHttpRequest.new(:success) request.should_receive(:get).and_return(request) EventMachine::HttpRequest.stub!(:new).and_return(request) + + EventMachine.run { @handler.add_get_request("http://www.google.com/") @handler.size.should == 1 @handler.process @handler.size.should == 0 + EventMachine.stop } end it 'should only retry a bad request three times ' do - EM.next_tick{ request = FakeHttpRequest.new(:failure) request.should_receive(:get).exactly(MessageHandler::NUM_TRIES).times.and_return(request) EventMachine::HttpRequest.stub!(:new).and_return(request) - @handler.add_get_request("http://www.google.com/") + EventMachine.run { @handler.add_get_request("http://asdfsdajfsdfbasdj.com/") @handler.size.should == 1 @handler.process @handler.size.should == 0 - } + + EventMachine.stop + } end end end @@ -54,67 +56,76 @@ describe MessageHandler do it 'should be able to add a post message to the queue' do - EM.next_tick{ + EventMachine.run { @handler.size.should ==0 @handler.add_post_request(@message_urls.first, @message_body) @handler.size.should == 1 - } + + EventMachine.stop + } end it 'should be able to insert many posts into the queue' do - EM.next_tick{ + EventMachine.run { @handler.size.should == 0 @handler.add_post_request(@message_urls, @message_body) @handler.size.should == @message_urls.size - } + EventMachine.stop + } end it 'should post a single message to a given URL' do - EM.next_tick{ request = FakeHttpRequest.new(:success) request.should_receive(:post).and_return(request) EventMachine::HttpRequest.stub!(:new).and_return(request) + EventMachine.run{ @handler.add_post_request(@message_urls.first, @message_body) @handler.size.should == 1 @handler.process @handler.size.should == 0 - } + + EventMachine.stop + + } end end describe "Mixed Queries" do it 'should process both POST and GET requests in the same queue' do - EM.next_tick{ - request = FakeHttpRequest.new(:success) request.should_receive(:get).exactly(3).times.and_return(request) request.should_receive(:post).exactly(3).times.and_return(request) EventMachine::HttpRequest.stub!(:new).and_return(request) + EventMachine.run{ @handler.add_post_request(@message_urls,@message_body) @handler.size.should == 3 @handler.add_get_request(@message_urls) @handler.size.should == 6 @handler.process - #timer = EventMachine::Timer.new(1) do + timer = EventMachine::Timer.new(1) do @handler.size.should == 0 - #end - } + EventMachine.stop + end + } end it 'should be able to have seperate POST and GET have different callbacks' do - EM.next_tick{ request = FakeHttpRequest.new(:success) request.should_receive(:get).exactly(1).times.and_return(request) request.should_receive(:post).exactly(1).times.and_return(request) @handler.should_receive(:send_to_seed).once EventMachine::HttpRequest.stub!(:new).and_return(request) + + EventMachine.run{ @handler.add_post_request(@message_urls.first,@message_body) @handler.add_get_request(@message_urls.first) @handler.process + + EventMachine.stop } end @@ -125,7 +136,6 @@ class FakeHttpRequest def initialize(callback_wanted) @callback = callback_wanted end - def response "NOTE YOU ARE IN FAKE HTTP" end @@ -139,5 +149,4 @@ class FakeHttpRequest b.call if @callback == :failure end end -EventMachine.stop -} + From 947f1a60e7fc31002a984e714ff7661fb82adb92 Mon Sep 17 00:00:00 2001 From: maxwell Date: Wed, 7 Jul 2010 18:59:32 -0700 Subject: [PATCH 05/10] RS MS added url for for the socket controller --- app/controllers/socket_controller.rb | 12 ++++++---- app/helpers/socket_helper.rb | 16 +++++++++---- .../status_messages/_status_message.html.haml | 6 ++--- spec/controllers/socket_controller_spec.rb | 24 +++++++++++++++---- spec/factories.rb | 1 + spec/helpers/socket_helper_spec.rb | 4 ++++ 6 files changed, 47 insertions(+), 16 deletions(-) create mode 100644 spec/helpers/socket_helper_spec.rb diff --git a/app/controllers/socket_controller.rb b/app/controllers/socket_controller.rb index 65f9518a0..a5c91f89f 100644 --- a/app/controllers/socket_controller.rb +++ b/app/controllers/socket_controller.rb @@ -1,27 +1,31 @@ class SocketController < ApplicationController + include ApplicationHelper + include SocketHelper + include Rails.application.routes.url_helpers + + def default_url_options() + {:host=> 'example.com'} + end def incoming(msg) puts msg end - def new_subscriber WebSocket.subscribe end - - def outgoing(object) puts "made it sucka" WebSocket.push_to_clients(action_hash(object)) end - def delete_subscriber(sid) WebSocket.unsubscribe(sid) end + # need a data strucutre to keep track of who is where #the way this is set up now, we have users on pages diff --git a/app/helpers/socket_helper.rb b/app/helpers/socket_helper.rb index 485b053b9..fa996d811 100644 --- a/app/helpers/socket_helper.rb +++ b/app/helpers/socket_helper.rb @@ -1,13 +1,17 @@ module SocketHelper - + include ApplicationHelper def obj_id(object) - object.is_a? Post ? object.id : object.post_id + (object.is_a? Post) ? object.id : object.post_id end - + def url_options + {:host => "", :only_path => true} + end + def action_hash(object) + begin - v = render_to_string(type_partial(object), :post => object) unless object.is_a? Retraction + v = render_to_string(:partial => type_partial(object), :locals => {:post => object}) unless object.is_a? Retraction rescue Exception => e puts "in failzord " + v.inspect @@ -18,5 +22,7 @@ module SocketHelper {:class =>object.class.to_s.underscore.pluralize, :html => v, :post_id => obj_id(object)} end + -end \ No newline at end of file + +end diff --git a/app/views/status_messages/_status_message.html.haml b/app/views/status_messages/_status_message.html.haml index f3e94c09d..1333640f9 100644 --- a/app/views/status_messages/_status_message.html.haml +++ b/app/views/status_messages/_status_message.html.haml @@ -1,14 +1,14 @@ %li.message{:id => post.id, :class => ("mine" if mine?(post))} %span.from - = link_to_person post.person + = link_to post.person.real_name, post.person = auto_link post.message %div.time = link_to(how_long_ago(post), status_message_path(post)) \-- = link_to "show comments (#{post.comments.count})", '#', :class => "show_post_comments" - = render "comments/comments", :post => post + = render "comments/comments", :post => post - if mine?(post) .destroy_link - = link_to 'Delete', status_message_path(post), :confirm => 'Are you sure?', :method => :delete, :remote => true + = link_to 'Delete', status_message_url(post), :confirm => 'Are you sure?', :method => :delete, :remote => true diff --git a/spec/controllers/socket_controller_spec.rb b/spec/controllers/socket_controller_spec.rb index 053175f97..8f3f47e76 100644 --- a/spec/controllers/socket_controller_spec.rb +++ b/spec/controllers/socket_controller_spec.rb @@ -2,8 +2,10 @@ require File.dirname(__FILE__) + '/../spec_helper' #require 'em-spec/rspec' describe SocketController do + render_views + before do - Factory.create(:user) + @user = Factory.create(:user) WebSocket.unstub!(:push_to_clients) WebSocket.unstub!(:unsubscribe) WebSocket.unstub!(:subscribe) @@ -19,11 +21,25 @@ describe SocketController do end it 'should add a new subscriber to the websocket channel' do - - puts "balls" WebSocket.initialize_channel - puts "foobar" @controller.new_subscriber.should == 1 end + describe 'actionhash' do + before do + @message = Factory.create(:status_message, :person => @user) + end + it 'should actionhash posts' do + hash = @controller.action_hash(@message) + hash[:html].include?(@message.message).should be_true + hash[:class].include?('status_message').should be_true + end + + it 'should actionhash retractions' do + retraction = Retraction.for @message + hash = @controller.action_hash(retraction) + hash[:class].include?('retraction').should be_true + hash[:html].should be_nil + end + end end diff --git a/spec/factories.rb b/spec/factories.rb index 37032592f..fa525a9a4 100644 --- a/spec/factories.rb +++ b/spec/factories.rb @@ -18,6 +18,7 @@ Factory.define :user do |u| u.sequence(:email) {|n| "bob#{n}@aol.com"} u.password "bluepin7" u.password_confirmation "bluepin7" + u.url "www.example.com" u.profile Profile.new( :first_name => "Bob", :last_name => "Smith" ) end diff --git a/spec/helpers/socket_helper_spec.rb b/spec/helpers/socket_helper_spec.rb new file mode 100644 index 000000000..45c77f564 --- /dev/null +++ b/spec/helpers/socket_helper_spec.rb @@ -0,0 +1,4 @@ +require File.dirname(__FILE__) + '/../spec_helper' +describe SocketHelper do + +end From 58ed75a28929dd544120c6ad6a5efaa6c0b91059 Mon Sep 17 00:00:00 2001 From: maxwell Date: Wed, 7 Jul 2010 22:20:15 -0700 Subject: [PATCH 06/10] MS socket now works in the server, but I can't figure out how to mock this stuff --- app/controllers/dashboard_controller.rb | 1 + app/controllers/socket_controller.rb | 37 ++++++++--------------- app/helpers/application_helper.rb | 4 +-- app/helpers/socket_helper.rb | 5 ++-- app/models/post.rb | 4 +-- app/views/js/_websocket_js.haml | 2 +- config/initializers/socket.rb | 6 ++-- lib/socket_render.rb | 40 ------------------------- spec/spec_helper.rb | 6 ++++ 9 files changed, 31 insertions(+), 74 deletions(-) delete mode 100644 lib/socket_render.rb diff --git a/app/controllers/dashboard_controller.rb b/app/controllers/dashboard_controller.rb index e0aa18da0..ce821988d 100644 --- a/app/controllers/dashboard_controller.rb +++ b/app/controllers/dashboard_controller.rb @@ -5,6 +5,7 @@ class DashboardController < ApplicationController def index @posts = Post.paginate :page => params[:page], :order => 'created_at DESC' + puts session.inspect end diff --git a/app/controllers/socket_controller.rb b/app/controllers/socket_controller.rb index a5c91f89f..c3c2df8f9 100644 --- a/app/controllers/socket_controller.rb +++ b/app/controllers/socket_controller.rb @@ -2,13 +2,16 @@ class SocketController < ApplicationController include ApplicationHelper include SocketHelper include Rails.application.routes.url_helpers + before_filter :authenticate_user! - def default_url_options() - {:host=> 'example.com'} - end + + + # def default_url_options() + # {:host=> 'example.com'} + # end def incoming(msg) - puts msg + puts "#{msg} connected!" end def new_subscriber @@ -16,32 +19,18 @@ class SocketController < ApplicationController end def outgoing(object) - puts "made it sucka" + begin + @_request = ActionDispatch::Request.new(:socket => true) WebSocket.push_to_clients(action_hash(object)) + rescue Exception => e + puts e.inspect + raise e + end end def delete_subscriber(sid) WebSocket.unsubscribe(sid) end - - -# need a data strucutre to keep track of who is where - -#the way this is set up now, we have users on pages - -#could have... a channel for every page/collection...not that cool -#or, have a single channel, which has a corresponding :current page => [sid] -# can i cherry pick subscribers from a a channel? - - -# we want all sorts of stuff that comes with being a controller -# like, protect from forgery, view rendering, etc - - -#these functions are not really routes -#so the question is, whats the best way to call them? - -#also, this is an input output controller end diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index dbceffe78..c476210ab 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -38,8 +38,8 @@ module ApplicationHelper end def owner_picture - default = "#{root_url}images/user/default.jpg" - image = "#{root_url}images/user/#{User.first.profile.last_name.gsub(/ /,'').downcase}.jpg" + default = "/images/user/default.jpg" + image = "/images/user/#{User.first.profile.last_name.gsub(/ /,'').downcase}.jpg" if File.exist?("public/images/user/#{User.first.profile.last_name.gsub(/ /,'').downcase}.jpg") image_tag image, :id => "user_picture" diff --git a/app/helpers/socket_helper.rb b/app/helpers/socket_helper.rb index fa996d811..fbdd37f7a 100644 --- a/app/helpers/socket_helper.rb +++ b/app/helpers/socket_helper.rb @@ -13,14 +13,15 @@ module SocketHelper begin v = render_to_string(:partial => type_partial(object), :locals => {:post => object}) unless object.is_a? Retraction + rescue Exception => e - puts "in failzord " + v.inspect + puts "web socket view rendering failed for some reason." + v.inspect puts object.inspect puts e.message raise e end - {:class =>object.class.to_s.underscore.pluralize, :html => v, :post_id => obj_id(object)} + {:class =>object.class.to_s.underscore.pluralize, :html => v, :post_id => obj_id(object)}.to_json end diff --git a/app/models/post.rb b/app/models/post.rb index b8eb39dc3..266e16d0b 100644 --- a/app/models/post.rb +++ b/app/models/post.rb @@ -53,11 +53,11 @@ class Post end def send_to_view - WebSocket.push_to_clients(self) + SocketController.new.outgoing(self) end def remove_from_view - WebSocket.push_to_clients(Retraction.for(self)) + SocketController.new.outgoing(Retraction.for(self)) end end diff --git a/app/views/js/_websocket_js.haml b/app/views/js/_websocket_js.haml index 93286423c..a4ec035e2 100644 --- a/app/views/js/_websocket_js.haml +++ b/app/views/js/_websocket_js.haml @@ -8,7 +8,7 @@ function debug(str){ $("#debug").append("

" + str); }; ws = new WebSocket("ws://#{request.host}:8080/"); - ws.onmessage = function(evt) { + ws.onmessage = function(evt) { var obj = jQuery.parseJSON(evt.data); debug("got a " + obj['class']); diff --git a/config/initializers/socket.rb b/config/initializers/socket.rb index ac79810fd..badb33c6f 100644 --- a/config/initializers/socket.rb +++ b/config/initializers/socket.rb @@ -13,7 +13,7 @@ module WebSocket :debug =>APP_CONFIG[:debug]) do |ws| ws.onopen { @ws = ws - sid = SocketController.new.new_subscriber(ws) + sid = SocketController.new.new_subscriber ws.onmessage { |msg| SocketController.new.incoming(msg) }#@channel.push msg; puts msg} @@ -24,10 +24,10 @@ module WebSocket def self.initialize_channel @channel = EM::Channel.new - puts @channel.inspect end def self.push_to_clients(html) + puts html @channel.push(html) end @@ -37,7 +37,7 @@ module WebSocket def self.subscribe - @channel.subscribe{ |msg| puts "hello #{msg}";@ws.send msg } + @channel.subscribe{ |msg| puts @ws.inspect; puts "ehllo" ; @ws.send msg } end end diff --git a/lib/socket_render.rb b/lib/socket_render.rb deleted file mode 100644 index 6f8bcbad9..000000000 --- a/lib/socket_render.rb +++ /dev/null @@ -1,40 +0,0 @@ -# module SocketRenderer -# require 'app/helpers/application_helper' -# def self.instantiate_view -# @view = ActionView::Base.new(ActionController::Base.view_paths, {}) -# class << @view -# include ApplicationHelper -# include Rails.application.routes.url_helpers -# include ActionController::RequestForgeryProtection::ClassMethods -# def protect_against_forgery? -# false -# end -# end -# end -# -# def self.view_hash(object) -# begin -# v = view_for(object) unless object.is_a? Retraction -# -# rescue Exception => e -# puts "in failzord " + v.inspect -# puts object.inspect -# puts e.message -# raise e -# end -# -# {:class =>object.class.to_s.underscore.pluralize, :html => v, :post_id => obj_id(object)} -# end -# -# def self.view_for(object) -# @view.render @view.type_partial(object), :post => object -# end -# -# def self.obj_id(object) -# if object.is_a? Post -# object.id -# else -# object.post_id -# end -# end -# end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 8a8b09e50..268305b32 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -24,6 +24,12 @@ RSpec.configure do |config| config.before(:each) do DatabaseCleaner.start + SocketController.stub!(:incoming).and_return(true) + SocketController.stub!(:new_subscriber).and_return(true) + SocketController.stub!(:outgoing).and_return(true) + SocketController.stub!(:delete_subscriber).and_return(true) + + WebSocket.stub!(:push_to_clients).and_return("stub") WebSocket.stub!(:unsubscribe).and_return("stub") WebSocket.stub!(:subscribe).and_return("stub") From 29eb883f764965f0d30c0cbe2a14176249c2a42b Mon Sep 17 00:00:00 2001 From: maxwell Date: Thu, 8 Jul 2010 10:14:17 -0700 Subject: [PATCH 07/10] socket is now a controller --- app/controllers/dashboard_controller.rb | 1 - app/controllers/socket_controller.rb | 7 +----- app/helpers/socket_helper.rb | 9 +++----- config/initializers/socket.rb | 3 +-- spec/controllers/socket_controller_spec.rb | 27 +++++++++------------- spec/lib/message_handler_spec.rb | 1 + spec/spec_helper.rb | 18 +++++++-------- 7 files changed, 26 insertions(+), 40 deletions(-) diff --git a/app/controllers/dashboard_controller.rb b/app/controllers/dashboard_controller.rb index ce821988d..e0aa18da0 100644 --- a/app/controllers/dashboard_controller.rb +++ b/app/controllers/dashboard_controller.rb @@ -5,7 +5,6 @@ class DashboardController < ApplicationController def index @posts = Post.paginate :page => params[:page], :order => 'created_at DESC' - puts session.inspect end diff --git a/app/controllers/socket_controller.rb b/app/controllers/socket_controller.rb index c3c2df8f9..6046697b7 100644 --- a/app/controllers/socket_controller.rb +++ b/app/controllers/socket_controller.rb @@ -19,13 +19,8 @@ class SocketController < ApplicationController end def outgoing(object) - begin - @_request = ActionDispatch::Request.new(:socket => true) + @_request = ActionDispatch::Request.new({}) WebSocket.push_to_clients(action_hash(object)) - rescue Exception => e - puts e.inspect - raise e - end end def delete_subscriber(sid) diff --git a/app/helpers/socket_helper.rb b/app/helpers/socket_helper.rb index fbdd37f7a..36124a60d 100644 --- a/app/helpers/socket_helper.rb +++ b/app/helpers/socket_helper.rb @@ -1,26 +1,23 @@ module SocketHelper include ApplicationHelper - def obj_id(object) + + def obj_id(object) (object.is_a? Post) ? object.id : object.post_id end def url_options - {:host => "", :only_path => true} + {:host => ""} end def action_hash(object) - begin v = render_to_string(:partial => type_partial(object), :locals => {:post => object}) unless object.is_a? Retraction - - rescue Exception => e puts "web socket view rendering failed for some reason." + v.inspect puts object.inspect puts e.message raise e end - {:class =>object.class.to_s.underscore.pluralize, :html => v, :post_id => obj_id(object)}.to_json end diff --git a/config/initializers/socket.rb b/config/initializers/socket.rb index badb33c6f..d1fcfc315 100644 --- a/config/initializers/socket.rb +++ b/config/initializers/socket.rb @@ -27,7 +27,6 @@ module WebSocket end def self.push_to_clients(html) - puts html @channel.push(html) end @@ -37,7 +36,7 @@ module WebSocket def self.subscribe - @channel.subscribe{ |msg| puts @ws.inspect; puts "ehllo" ; @ws.send msg } + @channel.subscribe{ |msg| @ws.send msg } end end diff --git a/spec/controllers/socket_controller_spec.rb b/spec/controllers/socket_controller_spec.rb index 8f3f47e76..5f5a8b70f 100644 --- a/spec/controllers/socket_controller_spec.rb +++ b/spec/controllers/socket_controller_spec.rb @@ -1,23 +1,18 @@ require File.dirname(__FILE__) + '/../spec_helper' -#require 'em-spec/rspec' -describe SocketController do - render_views - +describe 'SocketController' do + render_views before do @user = Factory.create(:user) - WebSocket.unstub!(:push_to_clients) - WebSocket.unstub!(:unsubscribe) - WebSocket.unstub!(:subscribe) + SocketController.unstub!(:new) #EventMachine::WebSocket.stub!(:start) @controller = SocketController.new + stub_socket_controller end it 'should unstub the websocket' do WebSocket.initialize_channel - WebSocket.push_to_clients("what").should_not == "stub" - WebSocket.unsubscribe(1).should_not == "stub" - WebSocket.subscribe.should_not == "stub" + @controller.class.should == SocketController end it 'should add a new subscriber to the websocket channel' do @@ -30,16 +25,16 @@ describe SocketController do end it 'should actionhash posts' do - hash = @controller.action_hash(@message) - hash[:html].include?(@message.message).should be_true - hash[:class].include?('status_message').should be_true + json = @controller.action_hash(@message) + json.include?(@message.message).should be_true + json.include?('status_message').should be_true end it 'should actionhash retractions' do retraction = Retraction.for @message - hash = @controller.action_hash(retraction) - hash[:class].include?('retraction').should be_true - hash[:html].should be_nil + json = @controller.action_hash(retraction) + json.include?('retraction').should be_true + json.include?("html\":null").should be_true end end end diff --git a/spec/lib/message_handler_spec.rb b/spec/lib/message_handler_spec.rb index 3ec0a6e2c..553135b96 100644 --- a/spec/lib/message_handler_spec.rb +++ b/spec/lib/message_handler_spec.rb @@ -5,6 +5,7 @@ describe MessageHandler do @handler = MessageHandler.new @message_body = "I want to pump you up" @message_urls = ["http://www.google.com/", "http://yahoo.com/", "http://foo.com/"] + end describe 'GET messages' do diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 268305b32..a4d470af2 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -24,15 +24,7 @@ RSpec.configure do |config| config.before(:each) do DatabaseCleaner.start - SocketController.stub!(:incoming).and_return(true) - SocketController.stub!(:new_subscriber).and_return(true) - SocketController.stub!(:outgoing).and_return(true) - SocketController.stub!(:delete_subscriber).and_return(true) - - - WebSocket.stub!(:push_to_clients).and_return("stub") - WebSocket.stub!(:unsubscribe).and_return("stub") - WebSocket.stub!(:subscribe).and_return("stub") + stub_socket_controller end config.after(:each) do @@ -40,3 +32,11 @@ RSpec.configure do |config| end end + def stub_socket_controller + mock_socket_controller = mock('socket mock') + mock_socket_controller.stub!(:incoming).and_return(true) + mock_socket_controller.stub!(:new_subscriber).and_return(true) + mock_socket_controller.stub!(:outgoing).and_return(true) + mock_socket_controller.stub!(:delete_subscriber).and_return(true) + SocketController.stub!(:new).and_return(mock_socket_controller) + end From 6293f9f5855f1363693e82d0d91c119e2cf9f56c Mon Sep 17 00:00:00 2001 From: maxwell Date: Thu, 8 Jul 2010 10:14:17 -0700 Subject: [PATCH 08/10] socket is now a controller --- app/controllers/dashboard_controller.rb | 1 - app/controllers/socket_controller.rb | 7 +----- app/helpers/socket_helper.rb | 9 +++----- config/initializers/socket.rb | 3 +-- spec/controllers/socket_controller_spec.rb | 27 +++++++++------------- spec/lib/message_handler_spec.rb | 1 + spec/spec_helper.rb | 18 +++++++-------- 7 files changed, 26 insertions(+), 40 deletions(-) diff --git a/app/controllers/dashboard_controller.rb b/app/controllers/dashboard_controller.rb index ce821988d..e0aa18da0 100644 --- a/app/controllers/dashboard_controller.rb +++ b/app/controllers/dashboard_controller.rb @@ -5,7 +5,6 @@ class DashboardController < ApplicationController def index @posts = Post.paginate :page => params[:page], :order => 'created_at DESC' - puts session.inspect end diff --git a/app/controllers/socket_controller.rb b/app/controllers/socket_controller.rb index c3c2df8f9..6046697b7 100644 --- a/app/controllers/socket_controller.rb +++ b/app/controllers/socket_controller.rb @@ -19,13 +19,8 @@ class SocketController < ApplicationController end def outgoing(object) - begin - @_request = ActionDispatch::Request.new(:socket => true) + @_request = ActionDispatch::Request.new({}) WebSocket.push_to_clients(action_hash(object)) - rescue Exception => e - puts e.inspect - raise e - end end def delete_subscriber(sid) diff --git a/app/helpers/socket_helper.rb b/app/helpers/socket_helper.rb index fbdd37f7a..36124a60d 100644 --- a/app/helpers/socket_helper.rb +++ b/app/helpers/socket_helper.rb @@ -1,26 +1,23 @@ module SocketHelper include ApplicationHelper - def obj_id(object) + + def obj_id(object) (object.is_a? Post) ? object.id : object.post_id end def url_options - {:host => "", :only_path => true} + {:host => ""} end def action_hash(object) - begin v = render_to_string(:partial => type_partial(object), :locals => {:post => object}) unless object.is_a? Retraction - - rescue Exception => e puts "web socket view rendering failed for some reason." + v.inspect puts object.inspect puts e.message raise e end - {:class =>object.class.to_s.underscore.pluralize, :html => v, :post_id => obj_id(object)}.to_json end diff --git a/config/initializers/socket.rb b/config/initializers/socket.rb index badb33c6f..d1fcfc315 100644 --- a/config/initializers/socket.rb +++ b/config/initializers/socket.rb @@ -27,7 +27,6 @@ module WebSocket end def self.push_to_clients(html) - puts html @channel.push(html) end @@ -37,7 +36,7 @@ module WebSocket def self.subscribe - @channel.subscribe{ |msg| puts @ws.inspect; puts "ehllo" ; @ws.send msg } + @channel.subscribe{ |msg| @ws.send msg } end end diff --git a/spec/controllers/socket_controller_spec.rb b/spec/controllers/socket_controller_spec.rb index 8f3f47e76..5f5a8b70f 100644 --- a/spec/controllers/socket_controller_spec.rb +++ b/spec/controllers/socket_controller_spec.rb @@ -1,23 +1,18 @@ require File.dirname(__FILE__) + '/../spec_helper' -#require 'em-spec/rspec' -describe SocketController do - render_views - +describe 'SocketController' do + render_views before do @user = Factory.create(:user) - WebSocket.unstub!(:push_to_clients) - WebSocket.unstub!(:unsubscribe) - WebSocket.unstub!(:subscribe) + SocketController.unstub!(:new) #EventMachine::WebSocket.stub!(:start) @controller = SocketController.new + stub_socket_controller end it 'should unstub the websocket' do WebSocket.initialize_channel - WebSocket.push_to_clients("what").should_not == "stub" - WebSocket.unsubscribe(1).should_not == "stub" - WebSocket.subscribe.should_not == "stub" + @controller.class.should == SocketController end it 'should add a new subscriber to the websocket channel' do @@ -30,16 +25,16 @@ describe SocketController do end it 'should actionhash posts' do - hash = @controller.action_hash(@message) - hash[:html].include?(@message.message).should be_true - hash[:class].include?('status_message').should be_true + json = @controller.action_hash(@message) + json.include?(@message.message).should be_true + json.include?('status_message').should be_true end it 'should actionhash retractions' do retraction = Retraction.for @message - hash = @controller.action_hash(retraction) - hash[:class].include?('retraction').should be_true - hash[:html].should be_nil + json = @controller.action_hash(retraction) + json.include?('retraction').should be_true + json.include?("html\":null").should be_true end end end diff --git a/spec/lib/message_handler_spec.rb b/spec/lib/message_handler_spec.rb index 3ec0a6e2c..553135b96 100644 --- a/spec/lib/message_handler_spec.rb +++ b/spec/lib/message_handler_spec.rb @@ -5,6 +5,7 @@ describe MessageHandler do @handler = MessageHandler.new @message_body = "I want to pump you up" @message_urls = ["http://www.google.com/", "http://yahoo.com/", "http://foo.com/"] + end describe 'GET messages' do diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 268305b32..a4d470af2 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -24,15 +24,7 @@ RSpec.configure do |config| config.before(:each) do DatabaseCleaner.start - SocketController.stub!(:incoming).and_return(true) - SocketController.stub!(:new_subscriber).and_return(true) - SocketController.stub!(:outgoing).and_return(true) - SocketController.stub!(:delete_subscriber).and_return(true) - - - WebSocket.stub!(:push_to_clients).and_return("stub") - WebSocket.stub!(:unsubscribe).and_return("stub") - WebSocket.stub!(:subscribe).and_return("stub") + stub_socket_controller end config.after(:each) do @@ -40,3 +32,11 @@ RSpec.configure do |config| end end + def stub_socket_controller + mock_socket_controller = mock('socket mock') + mock_socket_controller.stub!(:incoming).and_return(true) + mock_socket_controller.stub!(:new_subscriber).and_return(true) + mock_socket_controller.stub!(:outgoing).and_return(true) + mock_socket_controller.stub!(:delete_subscriber).and_return(true) + SocketController.stub!(:new).and_return(mock_socket_controller) + end From 09b79293f08e6ae66323540deb7a68df057450fb Mon Sep 17 00:00:00 2001 From: maxwell Date: Thu, 8 Jul 2010 10:19:58 -0700 Subject: [PATCH 09/10] merged master --- app/models/comment.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/comment.rb b/app/models/comment.rb index 53955e0c9..55cfe7890 100644 --- a/app/models/comment.rb +++ b/app/models/comment.rb @@ -36,6 +36,6 @@ class Comment def send_to_view - WebSocket.push_to_clients(self) + SocketController.new.outgoing(self) end end From 4819ce694b7b034a2a609370bcbe718601a28ada Mon Sep 17 00:00:00 2001 From: Raphael Date: Thu, 8 Jul 2010 10:27:22 -0700 Subject: [PATCH 10/10] removed emspec from gemfile --- Gemfile | 1 - app/controllers/users_controller.rb | 4 ++++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/Gemfile b/Gemfile index d36727342..fb8243e53 100644 --- a/Gemfile +++ b/Gemfile @@ -32,7 +32,6 @@ group :test do gem 'autotest' gem 'factory_girl_rails' gem 'database_cleaner' - gem 'em-spec', :git => 'http://github.com/danielsdeleo/em-spec.git' end group :development do diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index eb6a95578..91c199c97 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -4,4 +4,8 @@ class UsersController < ApplicationController def index @users = User.sort(:created_at.desc).all end + + def show + @user = User.find(params[:id]) + end end