Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Provide an 'Add another file link' that uses Javascript so that users…

… can upload more than one file
  • Loading branch information...
commit 982ddf6241a78a9e6547e16af29086627d9e72d2 1 parent 27060df
Ryan Bigg authored May 07, 2011
8  Gemfile
... ...
@@ -1,8 +1,8 @@
1 1
 source 'http://rubygems.org'
2 2
 
3  
-gem 'rails',     '3.1.0.beta1'
  3
+gem 'rails', :path => "~/Sites/rails/edge-rails"
4 4
 # gem 'arel',      :git => 'git://github.com/rails/arel.git'
5  
-# gem 'rack',      '1.3.0.beta'
  5
+gem 'rack', :path => "~/Sites/gems/rack"
6 6
 # gem 'sprockets', :git => "git://github.com/sstephenson/sprockets.git"
7 7
 
8 8
 gem 'sqlite3'
@@ -17,6 +17,8 @@ gem 'cancan'
17 17
 
18 18
 gem 'paperclip'
19 19
 
  20
+gem 'jquery-rails'
  21
+
20 22
 group :test, :development do
21 23
   gem 'rspec-rails', '~> 2.5'
22 24
 end
@@ -24,7 +26,7 @@ end
24 26
 group :test do
25 27
   gem 'rack-test', :git => "git://github.com/radar/rack-test"
26 28
   gem 'cucumber-rails'
27  
-  gem 'capybara'
  29
+  gem 'capybara', :git => "git://github.com/radar/capybara"
28 30
   gem 'database_cleaner'
29 31
   gem 'factory_girl'
30 32
   gem 'launchy'
74  Gemfile.lock
... ...
@@ -1,12 +1,29 @@
1 1
 GIT
  2
+  remote: git://github.com/radar/capybara
  3
+  revision: 43ea95f338cb9371b7b27b2082e18349873ff042
  4
+  specs:
  5
+    capybara (1.0.0.beta1)
  6
+      mime-types (>= 1.16)
  7
+      nokogiri (>= 1.3.3)
  8
+      rack (>= 1.0.0)
  9
+      rack-test (>= 0.5.4)
  10
+      selenium-webdriver (~> 0.2.0)
  11
+      xpath (~> 0.1.4)
  12
+
  13
+GIT
2 14
   remote: git://github.com/radar/rack-test
3 15
   revision: a4b7ef0a736d95205bdb8d79c1abb182cb4a8a71
4 16
   specs:
5 17
     rack-test (0.6.0)
6 18
       rack (>= 1.0)
7 19
 
8  
-GEM
9  
-  remote: http://rubygems.org/
  20
+PATH
  21
+  remote: ~/Sites/gems/rack
  22
+  specs:
  23
+    rack (1.3.0.beta)
  24
+
  25
+PATH
  26
+  remote: ~/Sites/rails/edge-rails
10 27
   specs:
11 28
     actionmailer (3.1.0.beta1)
12 29
       actionpack (= 3.1.0.beta1)
@@ -38,20 +55,28 @@ GEM
38 55
       activesupport (= 3.1.0.beta1)
39 56
     activesupport (3.1.0.beta1)
40 57
       multi_json (~> 1.0)
  58
+    rails (3.1.0.beta1)
  59
+      actionmailer (= 3.1.0.beta1)
  60
+      actionpack (= 3.1.0.beta1)
  61
+      activerecord (= 3.1.0.beta1)
  62
+      activeresource (= 3.1.0.beta1)
  63
+      activesupport (= 3.1.0.beta1)
  64
+      bundler (~> 1.0)
  65
+      railties (= 3.1.0.beta1)
  66
+    railties (3.1.0.beta1)
  67
+      actionpack (= 3.1.0.beta1)
  68
+      activesupport (= 3.1.0.beta1)
  69
+      rack-ssl (~> 1.3.2)
  70
+      rake (>= 0.8.7)
  71
+      thor (~> 0.14.6)
  72
+
  73
+GEM
  74
+  remote: http://rubygems.org/
  75
+  specs:
41 76
     arel (2.1.0)
42 77
     bcrypt-ruby (2.1.4)
43 78
     builder (3.0.0)
44 79
     cancan (1.6.4)
45  
-    capybara (0.4.1.2)
46  
-      celerity (>= 0.7.9)
47  
-      culerity (>= 0.2.4)
48  
-      mime-types (>= 1.16)
49  
-      nokogiri (>= 1.3.3)
50  
-      rack (>= 1.0.0)
51  
-      rack-test (>= 0.5.4)
52  
-      selenium-webdriver (>= 0.0.27)
53  
-      xpath (~> 0.1.3)
54  
-    celerity (0.8.9)
55 80
     childprocess (0.1.8)
56 81
       ffi (~> 1.0.6)
57 82
     coffee-script (2.2.0)
@@ -69,7 +94,6 @@ GEM
69 94
       cucumber (>= 0.10.1)
70 95
       nokogiri (>= 1.4.4)
71 96
       rack-test (>= 0.5.7)
72  
-    culerity (0.2.15)
73 97
     database_cleaner (0.6.7)
74 98
     devise (1.2.1)
75 99
       bcrypt-ruby (~> 2.1.2)
@@ -89,6 +113,9 @@ GEM
89 113
       json (>= 1.4.6)
90 114
     hike (1.0.0)
91 115
     i18n (0.6.0beta1)
  116
+    jquery-rails (0.2.7)
  117
+      rails (~> 3.0)
  118
+      thor (~> 0.14.4)
92 119
     json (1.5.1)
93 120
     json_pure (1.5.1)
94 121
     launchy (0.4.0)
@@ -106,27 +133,12 @@ GEM
106 133
       activerecord (>= 2.3.0)
107 134
       activesupport (>= 2.3.2)
108 135
     polyglot (0.3.1)
109  
-    rack (1.3.0.beta)
110 136
     rack-cache (1.0.1)
111 137
       rack (>= 0.4)
112 138
     rack-mount (0.7.2)
113 139
       rack (>= 1.0.0)
114 140
     rack-ssl (1.3.2)
115 141
       rack
116  
-    rails (3.1.0.beta1)
117  
-      actionmailer (= 3.1.0.beta1)
118  
-      actionpack (= 3.1.0.beta1)
119  
-      activerecord (= 3.1.0.beta1)
120  
-      activeresource (= 3.1.0.beta1)
121  
-      activesupport (= 3.1.0.beta1)
122  
-      bundler (~> 1.0)
123  
-      railties (= 3.1.0.beta1)
124  
-    railties (3.1.0.beta1)
125  
-      actionpack (= 3.1.0.beta1)
126  
-      activesupport (= 3.1.0.beta1)
127  
-      rack-ssl (~> 1.3.2)
128  
-      rake (>= 0.8.7)
129  
-      thor (~> 0.14.6)
130 142
     rake (0.8.7)
131 143
     rspec (2.5.0)
132 144
       rspec-core (~> 2.5.0)
@@ -169,7 +181,7 @@ PLATFORMS
169 181
 
170 182
 DEPENDENCIES
171 183
   cancan
172  
-  capybara
  184
+  capybara!
173 185
   coffee-script
174 186
   cucumber-rails
175 187
   database_cleaner
@@ -177,10 +189,12 @@ DEPENDENCIES
177 189
   dynamic_form
178 190
   email_spec
179 191
   factory_girl
  192
+  jquery-rails
180 193
   launchy
181 194
   paperclip
  195
+  rack!
182 196
   rack-test!
183  
-  rails (= 3.1.0.beta1)
  197
+  rails!
184 198
   rspec-rails (~> 2.5)
185 199
   sass (~> 3.1.0.alpha)
186 200
   sqlite3
10  app/assets/javascripts/tickets.js.coffee
... ...
@@ -1,3 +1,13 @@
1 1
 # Place all the behaviors and hooks related to the matching controller here.
2 2
 # All this logic will automatically be available in application.js.
3 3
 # You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/
  4
+
  5
+$(->
  6
+  $('a#add_another_file').click(->
  7
+    url = "/files/new?number=" + $('#files input').length
  8
+    $.get(url, 
  9
+      (data)->
  10
+        $('#files').append(data)
  11
+    )
  12
+  )
  13
+)
2  app/assets/stylesheets/tickets.css.scss
@@ -3,3 +3,5 @@
3 3
   They will automatically be included in application.css.
4 4
   You can use Sass (SCSS) here: http://sass-lang.com/
5 5
 */
  6
+
  7
+$('a#add_another_file').click($ -> alert("whoops!"))
22  app/controllers/files_controller.rb
... ...
@@ -0,0 +1,22 @@
  1
+class FilesController < ApplicationController
  2
+  before_filter :authenticate_user!
  3
+  def show
  4
+    asset = Asset.find(params[:id])
  5
+    if can?(:view, asset.ticket.project)
  6
+      send_file asset.asset.path, :filename     => asset.asset_file_name,
  7
+                                  :content_type => asset.asset_content_type 
  8
+    else
  9
+      flash[:alert] = "The asset you were looking for could not be found."
  10
+      redirect_to root_path
  11
+    end
  12
+  end
  13
+  
  14
+  def new
  15
+    @ticket = Ticket.new
  16
+    asset = @ticket.assets.build
  17
+    render :partial => "files/form", 
  18
+           :locals => { :number => params[:number].to_i,
  19
+                        :asset => asset }
  20
+  end
  21
+
  22
+end
2  app/controllers/tickets_controller.rb
@@ -11,7 +11,7 @@ class TicketsController < ApplicationController
11 11
   
12 12
   def new
13 13
     @ticket = @project.tickets.build
14  
-    3.times { @ticket.assets.build }
  14
+    @ticket.assets.build
15 15
   end
16 16
   
17 17
   def create
2  app/helpers/files_helper.rb
... ...
@@ -0,0 +1,2 @@
  1
+module FilesHelper
  2
+end
8  app/views/files/_form.html.erb
... ...
@@ -0,0 +1,8 @@
  1
+<%= fields_for @ticket do |f| %>
  2
+  <%= f.fields_for :assets, :child_index => number do |asset| %>
  3
+    <p>
  4
+      <%= asset.label :asset, "File ##{number += 1}" %>
  5
+      <%= asset.file_field :asset %>
  6
+    </p>
  7
+  <% end %>
  8
+<% end %>
15  app/views/tickets/_form.html.erb
@@ -9,11 +9,14 @@
9 9
     <%= f.text_area :description %>
10 10
   </p>
11 11
   <% number = 0 %>
12  
-  <%= f.fields_for :assets do |asset| %>
13  
-    <p>
14  
-      <%= asset.label :asset, "File ##{number += 1}" %>
15  
-      <%= asset.file_field :asset %>
16  
-    </p>
17  
-  <% end %>
  12
+  <div id='files'>
  13
+    <%= f.fields_for :assets, :child_index => number do |asset| %>
  14
+      <p>
  15
+        <%= asset.label :asset, "File ##{number += 1}" %>
  16
+        <%= asset.file_field :asset %>
  17
+      </p>
  18
+    <% end %>
  19
+  </div>
  20
+  <%= link_to "Add another file", 'javascript:', :id => "add_another_file" %>
18 21
   <%= f.submit %>
19 22
 <% end %>
2  config/routes.rb
@@ -10,7 +10,7 @@
10 10
     resources :tickets
11 11
   end
12 12
 
13  
-  resources :assets
  13
+  resources :files
14 14
 
15 15
   namespace :admin do
16 16
     root :to => "base#index"
5  features/creating_tickets.feature
@@ -35,14 +35,15 @@ Feature: Creating Tickets
35 35
     Then I should see "Ticket has not been created."
36 36
     And I should see "Description is too short"
37 37
     
  38
+  @javascript
38 39
   Scenario: Creating a ticket with an attachment
39 40
     When I fill in "Title" with "Add documentation for blink tag"
40 41
     And I fill in "Description" with "The blink tag has an undocumented speed attribute"
41 42
     And I attach the file "spec/fixtures/speed.txt" to "File #1"
  43
+    And I follow "Add another file"
42 44
     And I attach the file "spec/fixtures/spin.txt" to "File #2"
43  
-    And I attach the file "spec/fixtures/gradient.txt" to "File #3"
44 45
     And I press "Create Ticket"
45 46
     Then I should see "Ticket has been created."
46 47
     And I should see "speed.txt" within "#ticket .assets"
47 48
     And I should see "spin.txt" within "#ticket .assets"
48  
-    And I should see "gradient.txt" within "#ticket .assets"
  49
+    When I follow "speed.txt"
1  files/2
... ...
@@ -0,0 +1 @@
  1
+Spinning blink tags have a 200% higher click rate!
1  files/3
... ...
@@ -0,0 +1 @@
  1
+Spinning blink tags have a 200% higher click rate!
1  files/4
... ...
@@ -0,0 +1 @@
  1
+Spinning blink tags have a 200% higher click rate!
1  files/5
... ...
@@ -0,0 +1 @@
  1
+The blink tag can blink faster if you use the speed="hyper" attribute.
1  files/6
... ...
@@ -0,0 +1 @@
  1
+Spinning blink tags have a 200% higher click rate!
42  spec/controllers/files_controller_spec.rb
... ...
@@ -0,0 +1,42 @@
  1
+require 'spec_helper'
  2
+
  3
+describe FilesController do
  4
+  let(:project) { Factory(:project) }
  5
+  let(:ticket) { Factory(:ticket, :project => project) }
  6
+  let(:good_user) { create_user! }
  7
+  let(:bad_user) { create_user! }
  8
+  
  9
+  let(:path) { Rails.root + "spec/fixtures/speed.txt" }
  10
+  let(:asset) do
  11
+    ticket.assets.create(:asset => File.open(path))
  12
+  end
  13
+
  14
+  before do
  15
+    good_user.permissions.create!(:action => "view", :thing => project)
  16
+  end
  17
+  
  18
+  context "users with access" do
  19
+
  20
+    before do
  21
+      sign_in(:user, good_user)
  22
+    end
  23
+
  24
+    it "can access assets in a project" do
  25
+      get 'show', :id => asset.id
  26
+      response.body.should eql(File.read(path))
  27
+    end
  28
+  end
  29
+  
  30
+  context "users without access" do
  31
+    before do
  32
+      sign_in(:user, bad_user)
  33
+    end
  34
+
  35
+    it "cannot access assets in this project" do
  36
+      get 'show', :id => asset.id
  37
+      response.should redirect_to(root_path)
  38
+      flash[:alert].should eql("The asset you were looking for could not be found.")
  39
+    end
  40
+  end
  41
+  
  42
+end
15  spec/helpers/files_helper_spec.rb
... ...
@@ -0,0 +1,15 @@
  1
+require 'spec_helper'
  2
+
  3
+# Specs in this file have access to a helper object that includes
  4
+# the AssetsHelper. For example:
  5
+#
  6
+# describe AssetsHelper do
  7
+#   describe "string concat" do
  8
+#     it "concats two strings with spaces" do
  9
+#       helper.concat_strings("this","that").should == "this that"
  10
+#     end
  11
+#   end
  12
+# end
  13
+describe FilesHelper do
  14
+  pending "add some examples to (or delete) #{__FILE__}"
  15
+end

0 notes on commit 982ddf6

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