Skip to content
Browse files

Changes for Loccasions 7: Foreman, Occasions, Inherited Resources

  • Loading branch information...
1 parent 515f6aa commit 2c1de76fa5f8f83f90d969df00b2eb1f2e4d8b8b @ruprict committed Nov 9, 2011
View
2 Gemfile
@@ -9,7 +9,7 @@ gem 'haml-rails', '~> 0.3.4'
gem 'bson_ext', '~> 1.4.0'
gem 'rails-backbone', "~> 0.5.3"
-
+gem "inherited_resources", "~> 1.3.0"
# Gems used only for assets and not required
# in production environments by default.
group :assets do
View
19 Gemfile.lock
@@ -57,7 +57,7 @@ GEM
bcrypt-ruby (~> 3.0)
orm_adapter (~> 0.0.3)
warden (~> 1.0.3)
- diff-lcs (1.1.2)
+ diff-lcs (1.1.3)
ejs (1.0.0)
erubis (2.7.0)
execjs (1.2.4)
@@ -67,6 +67,9 @@ GEM
factory_girl (~> 2.0.0)
railties (>= 3.0.0)
ffi (1.0.9)
+ foreman (0.24.0)
+ term-ansicolor (~> 1.0.5)
+ thor (>= 0.13.6)
guard (0.7.0)
thor (~> 0.14.6)
guard-rspec (0.4.5)
@@ -116,7 +119,7 @@ GEM
nokogiri (1.5.0)
orm_adapter (0.0.5)
polyglot (0.3.2)
- rack (1.3.4)
+ rack (1.3.5)
rack-cache (1.0.3)
rack (>= 0.4)
rack-mount (0.8.3)
@@ -146,6 +149,7 @@ GEM
thor (~> 0.14.6)
rake (0.9.2)
rdoc (3.9.4)
+ responders (0.6.4)
rspec (2.6.0)
rspec-core (~> 2.6.0)
rspec-expectations (~> 2.6.0)
@@ -169,17 +173,18 @@ GEM
sass (>= 3.1.4)
sprockets (~> 2.0.0)
tilt (~> 1.3.2)
- selenium-webdriver (2.8.0)
+ selenium-webdriver (2.10.0)
childprocess (>= 0.2.1)
- ffi (>= 1.0.7)
+ ffi (= 1.0.9)
json_pure
rubyzip
sexp_processor (3.0.6)
spork (0.9.0.rc9)
sprockets (2.0.0)
hike (~> 1.2)
rack (~> 1.0)
- tilt (!= 1.3.0, ~> 1.1)
+ tilt (~> 1.1, != 1.3.0)
+ term-ansicolor (1.0.6)
thor (0.14.6)
tilt (1.3.3)
treetop (1.4.10)
@@ -204,12 +209,14 @@ DEPENDENCIES
database_cleaner (~> 0.6.7)
devise (~> 1.4.6)
factory_girl_rails (~> 1.1.0)
+ foreman (~> 0.24.0)
guard-rspec (~> 0.4.5)
guard-spork (~> 0.2.1)
haml (~> 3.1.2)
haml-rails (~> 0.3.4)
hpricot (~> 0.8.4)
- jasmine (~> 1.1.0.rc3)
+ inherited_resources (~> 1.3.0)
+ jasmine (~> 1.1.2)
jquery-rails
launchy (~> 2.0.5)
mongoid (~> 2.2.0)
View
3 app/assets/javascripts/occasions.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/
View
21 app/assets/stylesheets/occasions.css.scss
@@ -0,0 +1,21 @@
+// Place all the styles related to the occasions controller here.
+// They will automatically be included in application.css.
+// You can use Sass (SCSS) here: http://sass-lang.com/
+
+.coordinate_input {
+ float:left;
+ padding: 0 0.5em;
+}
+
+.coordinate_input input, .date_field input{
+ float:left;
+ width: 5em;
+ padding-right: .5em;
+}
+.note_field {
+ clear: both;
+}
+.note_field textarea {
+ width: 35em;
+ height: 5em;
+}
View
6 app/controllers/events_controller.rb
@@ -7,11 +7,12 @@ def index
def show
@event = current_user.events.find(params[:id])
+ Rails.logger.info("*** Event occasions: #{@event.occasions.inspect}")
end
def create
event = current_user.events.build(params[:event])
- event.save
+ event.save!
redirect_to events_path
end
@@ -23,8 +24,7 @@ def edit
def update
event = current_user.events.find(params[:id])
- event.update_attributes(params[:event])
- event.save
+ event.update_attributes!(params[:event])
redirect_to events_path
end
View
11 app/controllers/occasions_controller.rb
@@ -0,0 +1,11 @@
+class OccasionsController < InheritedResources::Base
+ belongs_to :event
+ actions :all, :except => [:show, :index]
+
+
+ # Need to override this from inherited_resources
+ # to scope the association chain to the current_user
+ def begin_of_association_chain
+ current_user
+ end
+end
View
2 app/helpers/occasions_helper.rb
@@ -0,0 +1,2 @@
+module OccasionsHelper
+end
View
3 app/models/event.rb
@@ -3,5 +3,8 @@ class Event
field :name, :type => String
field :description, :type => String
embedded_in :user, :inverse_of => :events
+ embeds_many :occasions
validates :user, :name, :presence => true
+
+ attr_accessible :name, :description
end
View
11 app/models/occasion.rb
@@ -0,0 +1,11 @@
+class Occasion
+ include Mongoid::Document
+ field :occurred_at, :type => Time
+ field :latitude, :type => Float
+ field :longitude, :type => Float
+ field :note, :type => String
+ embedded_in :event, :inverse_of => :occasions
+ validates :occurred_at, :latitude, :longitude, :presence => true
+
+ attr_accessible :occurred_at, :latitude, :longitude, :note
+end
View
7 app/views/events/_event.html.haml
@@ -0,0 +1,7 @@
+%span.del_form
+ =button_to "X", event, :confirm => "Are you sure?", :method => :delete
+%span.event_name
+ = link_to event.name, edit_event_path(event)
+%span.event_details
+ = link_to "Show Details", event_path(event)
+%span.event_description= event.description
View
8 app/views/events/index.html.haml
@@ -3,13 +3,7 @@
%ul#events
- for event in @events
%li{:class => @event == event ? :selected : nil}
- %span.del_form
- =button_to "X", event, :confirm => "Are you sure?", :method => :delete
- %span.event_name
- = link_to event.name, edit_event_path(event)
- %span.event_details
- = link_to "Show Details", event_path(event)
- %span.event_description= event.description
+ = render :partial => "event", :locals => {:event => event}
%div.clear
= form_for @event || Event.new do |f|
= f.label :name
View
22 app/views/events/show.html.haml
@@ -1,2 +1,24 @@
%h2= @event.name
.description= @event.description
+%div#map.twelve.columns.alpha
+%ul#occasions.four.columns.omega
+ - for occasion in @event.occasions
+ %li
+ = render :partial => "occasions/occasion", :locals => {:occasion => occasion}
+%div.clear
+%div#occasion_form
+ = form_for [@event, current_user.events.find(@event.id).occasions.build()] do |f|
+ %div.coordinate_input
+ = f.label :latitude
+ = f.text_field :latitude
+ %div.coordinate_input
+ = f.label :longitude
+ = f.text_field :longitude
+ %div.date_field
+ = f.label :occurred_at
+ = f.text_field :occurred_at
+ %div.note_field
+ = f.label :note
+ = f.text_area :note
+ = f.submit "Add"
+
View
6 app/views/occasions/_occasion.html.haml
@@ -0,0 +1,6 @@
+%span.del_form
+ =button_to "X", [occasion.event,occasion], :confirm => "Are you sure?", :method => :delete
+%span.occasion_name
+ = link_to occasion.occurred_at.to_s(:short), edit_event_occasion_path(@event, occasion)
+%span.occasion_note
+ = occasion.note
View
7 config/initializers/inherited_resources.rb
@@ -0,0 +1,7 @@
+module MongoidActions
+ def collection
+ get_collection_ivar || set_collection_ivar(end_of_association_chain.all)
+ end
+end
+
+InheritedResources::Base.send :include, MongoidActions
View
4 config/routes.rb
@@ -1,7 +1,9 @@
Loccasions::Application.routes.draw do
devise_for :users
- resources :events
+ resources :events do
+ resources :occasions
+ end
get 'events' => 'events#index', :as => :user_root
root :to => "home#index"
end
View
24 spec/acceptance/add_occasions_spec.rb
@@ -0,0 +1,24 @@
+require 'spec_helper'
+
+feature 'Add Occasion', %q{
+ As a registered user
+ I want to add an Occasion to an Event
+} do
+ background do
+ @user = Factory(:user)
+ login_user @user
+ @event = Factory(:event,:user => @user )
+ visit event_path(@event)
+ end
+ scenario "Add Occasion" do
+ page.should_not have_css("ul#occasions > li")
+ fill_in "Latitude", :with => 35.22
+ fill_in "Longitude", :with => -85.22
+ fill_in "Note", :with => "This is my new occasion"
+ fill_in "Occurred at", :with => '2011-11-03'
+ click_button "Add"
+ page.should have_css("ul#occasions > li", :count => 1)
+ page.should have_content("This is my new occasion")
+ end
+
+end
View
28 spec/acceptance/delete_occasions_spec.rb
@@ -0,0 +1,28 @@
+require 'spec_helper'
+
+feature "Delete Occasion", %q{
+ As a registered user,
+ I want to delete an occasion from an event
+} do
+
+ background do
+ Capybara.current_driver = :selenium
+ @occasion = Factory(:occasion)
+ login_user @occasion.event.user
+ visit event_path(@occasion.event)
+ end
+
+ after do
+ Capybara.use_default_driver
+ end
+
+ scenario "Delete Occasion" do
+ page.should have_content("Test Occasion")
+ page.should have_selector("form[action='/events/#{@occasion.event.id}/occasions/#{@occasion.id}'] input[value='delete']")
+ # auto confirm the dialog
+ page.execute_script('window.confirm = function() {return true;}')
+ click_button "X"
+ page.should_not have_content("Test Occasion")
+ end
+
+end
View
4 spec/acceptance/user_events_spec.rb
@@ -11,7 +11,7 @@
login_user(@user)
end
scenario "User is signed in" do
- visit events_path(@user)
+ visit events_path
page.should have_content(@user.name)
page.should have_content(@event.name)
end
@@ -25,7 +25,7 @@
@user = Factory.build(:user)
end
scenario "User is not signed in" do
- visit events_path(@user)
+ visit events_path
current_path.should == new_user_session_path
end
end
View
8 spec/factories.rb
@@ -11,4 +11,12 @@
user
end
+ factory :occasion do
+ latitude 35.1234
+ longitude -80.1234
+ occurred_at DateTime.now
+ note "Test Occasion"
+ event
+ end
+
end
View
38 spec/models/occasion_spec.rb
@@ -0,0 +1,38 @@
+require 'spec_helper'
+
+describe "Occasion" do
+ before do
+ @occasion = Factory.create(:occasion)
+ end
+ it "should have a time and date of occurrance" do
+ dt = Time.now
+ @occasion.occurred_at = dt
+
+ @occasion.occurred_at.to_s.should == dt.to_s
+ end
+
+ it "should have a latitude and longitude" do
+ @occasion.latitude = -85.000
+ @occasion.longitude = 35.3232
+
+ @occasion.latitude.should == -85.000
+ @occasion.longitude.should == 35.3232
+ end
+
+ it "should have a note" do
+ @occasion.note = "This thang went down"
+ @occasion.note.should == "This thang went down"
+ end
+
+ describe "validation" do
+ it "should require a latitude" do
+ @occasion.latitude = nil
+ @occasion.should_not be_valid
+ end
+
+ it "should require a longitude" do
+ @occasion.longitude = nil
+ @occasion.should_not be_valid
+ end
+ end
+end
View
5 spec/spec_helper.rb
@@ -49,7 +49,12 @@
Spork.each_run do
# This code will be run each time you run your specs.
+ # Reload our factories
+ FactoryGirl.factories.clear
+ Dir[Rails.root.join("spec/factories.rb")].each{|f| load f}
+ # Reload routes
+ Loccasions::Application.reload_routes!
end

0 comments on commit 2c1de76

Please sign in to comment.
Something went wrong with that request. Please try again.