tft_rails_dbc 0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (159) hide show
  1. data/.gitignore +6 -0
  2. data/.rvmrc +1 -0
  3. data/Gemfile +8 -0
  4. data/LICENSE +57 -0
  5. data/README.md +90 -0
  6. data/Rakefile +25 -0
  7. data/lib/generators/chapter07/begin/USAGE +27 -0
  8. data/lib/generators/chapter07/begin/begin_generator.rb +39 -0
  9. data/lib/generators/chapter07/begin/instructions.md +74 -0
  10. data/lib/generators/chapter07/begin/templates/app/controllers/application_controller.rb +8 -0
  11. data/lib/generators/chapter07/begin/templates/app/controllers/pages_controller.rb +11 -0
  12. data/lib/generators/chapter07/begin/templates/app/controllers/users_controller.rb +3 -0
  13. data/lib/generators/chapter07/begin/templates/app/helpers/application_helper.rb +12 -0
  14. data/lib/generators/chapter07/begin/templates/app/helpers/pages_helper.rb +2 -0
  15. data/lib/generators/chapter07/begin/templates/app/helpers/users_helper.rb +7 -0
  16. data/lib/generators/chapter07/begin/templates/app/models/user.rb +9 -0
  17. data/lib/generators/chapter07/begin/templates/app/views/layouts/_footer.html.erb +9 -0
  18. data/lib/generators/chapter07/begin/templates/app/views/layouts/_header.html.erb +10 -0
  19. data/lib/generators/chapter07/begin/templates/app/views/layouts/_stylesheets.html.erb +7 -0
  20. data/lib/generators/chapter07/begin/templates/app/views/layouts/application.html.erb +17 -0
  21. data/lib/generators/chapter07/begin/templates/app/views/pages/about.html.erb +7 -0
  22. data/lib/generators/chapter07/begin/templates/app/views/pages/contact.html.erb +5 -0
  23. data/lib/generators/chapter07/begin/templates/app/views/pages/home.html.erb +7 -0
  24. data/lib/generators/chapter07/begin/templates/app/views/users/show.html.erb +15 -0
  25. data/lib/generators/chapter07/begin/templates/config/initializers/devise.rb +194 -0
  26. data/lib/generators/chapter07/begin/templates/config/locales/devise.en.yml +50 -0
  27. data/lib/generators/chapter07/begin/templates/config/routes.rb.tt +17 -0
  28. data/lib/generators/chapter07/begin/templates/db/migrate/20110608224650_devise_create_users.rb +29 -0
  29. data/lib/generators/chapter07/begin/templates/db/schema.rb +34 -0
  30. data/lib/generators/chapter07/begin/templates/public/images/logo.png +0 -0
  31. data/lib/generators/chapter07/begin/templates/public/stylesheets/blueprint/ie.css +36 -0
  32. data/lib/generators/chapter07/begin/templates/public/stylesheets/blueprint/plugins/buttons/icons/cross.png +0 -0
  33. data/lib/generators/chapter07/begin/templates/public/stylesheets/blueprint/plugins/buttons/icons/key.png +0 -0
  34. data/lib/generators/chapter07/begin/templates/public/stylesheets/blueprint/plugins/buttons/icons/tick.png +0 -0
  35. data/lib/generators/chapter07/begin/templates/public/stylesheets/blueprint/plugins/buttons/readme.txt +32 -0
  36. data/lib/generators/chapter07/begin/templates/public/stylesheets/blueprint/plugins/buttons/screen.css +97 -0
  37. data/lib/generators/chapter07/begin/templates/public/stylesheets/blueprint/plugins/fancy-type/readme.txt +14 -0
  38. data/lib/generators/chapter07/begin/templates/public/stylesheets/blueprint/plugins/fancy-type/screen.css +71 -0
  39. data/lib/generators/chapter07/begin/templates/public/stylesheets/blueprint/plugins/link-icons/icons/doc.png +0 -0
  40. data/lib/generators/chapter07/begin/templates/public/stylesheets/blueprint/plugins/link-icons/icons/email.png +0 -0
  41. data/lib/generators/chapter07/begin/templates/public/stylesheets/blueprint/plugins/link-icons/icons/external.png +0 -0
  42. data/lib/generators/chapter07/begin/templates/public/stylesheets/blueprint/plugins/link-icons/icons/feed.png +0 -0
  43. data/lib/generators/chapter07/begin/templates/public/stylesheets/blueprint/plugins/link-icons/icons/im.png +0 -0
  44. data/lib/generators/chapter07/begin/templates/public/stylesheets/blueprint/plugins/link-icons/icons/lock.png +0 -0
  45. data/lib/generators/chapter07/begin/templates/public/stylesheets/blueprint/plugins/link-icons/icons/pdf.png +0 -0
  46. data/lib/generators/chapter07/begin/templates/public/stylesheets/blueprint/plugins/link-icons/icons/visited.png +0 -0
  47. data/lib/generators/chapter07/begin/templates/public/stylesheets/blueprint/plugins/link-icons/icons/xls.png +0 -0
  48. data/lib/generators/chapter07/begin/templates/public/stylesheets/blueprint/plugins/link-icons/readme.txt +18 -0
  49. data/lib/generators/chapter07/begin/templates/public/stylesheets/blueprint/plugins/link-icons/screen.css +42 -0
  50. data/lib/generators/chapter07/begin/templates/public/stylesheets/blueprint/plugins/rtl/readme.txt +10 -0
  51. data/lib/generators/chapter07/begin/templates/public/stylesheets/blueprint/plugins/rtl/screen.css +110 -0
  52. data/lib/generators/chapter07/begin/templates/public/stylesheets/blueprint/print.css +29 -0
  53. data/lib/generators/chapter07/begin/templates/public/stylesheets/blueprint/screen.css +265 -0
  54. data/lib/generators/chapter07/begin/templates/public/stylesheets/blueprint/src/forms.css +82 -0
  55. data/lib/generators/chapter07/begin/templates/public/stylesheets/blueprint/src/grid.css +280 -0
  56. data/lib/generators/chapter07/begin/templates/public/stylesheets/blueprint/src/grid.png +0 -0
  57. data/lib/generators/chapter07/begin/templates/public/stylesheets/blueprint/src/ie.css +79 -0
  58. data/lib/generators/chapter07/begin/templates/public/stylesheets/blueprint/src/print.css +92 -0
  59. data/lib/generators/chapter07/begin/templates/public/stylesheets/blueprint/src/reset.css +65 -0
  60. data/lib/generators/chapter07/begin/templates/public/stylesheets/blueprint/src/typography.css +123 -0
  61. data/lib/generators/chapter07/begin/templates/public/stylesheets/custom.css +137 -0
  62. data/lib/generators/chapter07/begin/templates/spec/controllers/pages_controller_07_spec.rb +48 -0
  63. data/lib/generators/chapter07/begin/templates/spec/controllers/users_controller_07_spec.rb +38 -0
  64. data/lib/generators/chapter07/begin/templates/spec/factories.rb +9 -0
  65. data/lib/generators/chapter07/begin/templates/spec/models/user_07_spec.rb +38 -0
  66. data/lib/generators/chapter07/begin/templates/spec/requests/layout_links_07_spec.rb +44 -0
  67. data/lib/generators/chapter07/begin/templates/spec/spec_helper.rb +39 -0
  68. data/lib/generators/chapter07/solutions/USAGE +21 -0
  69. data/lib/generators/chapter07/solutions/solutions_generator.rb +23 -0
  70. data/lib/generators/chapter07/solutions/templates/app/controllers/pages_controller.rb +18 -0
  71. data/lib/generators/chapter07/solutions/templates/app/controllers/users_controller.rb +8 -0
  72. data/lib/generators/chapter07/solutions/templates/app/models/user.rb +11 -0
  73. data/lib/generators/chapter07/solutions/templates/app/views/layouts/_footer.html.erb +10 -0
  74. data/lib/generators/chapter07/solutions/templates/app/views/layouts/_header.html.erb +11 -0
  75. data/lib/generators/chapter07/solutions/templates/app/views/pages/help.html.erb +4 -0
  76. data/lib/generators/chapter07/solutions/templates/app/views/pages/home.html.erb +7 -0
  77. data/lib/generators/chapter07/solutions/templates/app/views/users/show.html.erb +15 -0
  78. data/lib/generators/chapter08_09/begin/USAGE +24 -0
  79. data/lib/generators/chapter08_09/begin/begin_generator.rb +29 -0
  80. data/lib/generators/chapter08_09/begin/instructions.md +65 -0
  81. data/lib/generators/chapter08_09/begin/snippets/custom.css +49 -0
  82. data/lib/generators/chapter08_09/begin/templates/spec/controllers/devise/registrations_controller_08_spec.rb +83 -0
  83. data/lib/generators/chapter08_09/begin/templates/spec/requests/layout_links_09_spec.rb +35 -0
  84. data/lib/generators/chapter08_09/begin/templates/spec/requests/users_signup_08_spec.rb +36 -0
  85. data/lib/generators/chapter08_09/solutions/USAGE +18 -0
  86. data/lib/generators/chapter08_09/solutions/solutions_generator.rb +12 -0
  87. data/lib/generators/chapter08_09/solutions/templates/app/helpers/application_helper.rb +16 -0
  88. data/lib/generators/chapter08_09/solutions/templates/app/views/devise/passwords/edit.html.erb +16 -0
  89. data/lib/generators/chapter08_09/solutions/templates/app/views/devise/passwords/new.html.erb +12 -0
  90. data/lib/generators/chapter08_09/solutions/templates/app/views/devise/registrations/_fields.html.erb +16 -0
  91. data/lib/generators/chapter08_09/solutions/templates/app/views/devise/registrations/edit.html.erb +28 -0
  92. data/lib/generators/chapter08_09/solutions/templates/app/views/devise/registrations/new.html.erb +13 -0
  93. data/lib/generators/chapter08_09/solutions/templates/app/views/devise/sessions/new.html.erb +17 -0
  94. data/lib/generators/chapter08_09/solutions/templates/app/views/devise/shared/_links.erb +25 -0
  95. data/lib/generators/chapter08_09/solutions/templates/app/views/layouts/_header.html.erb +19 -0
  96. data/lib/generators/chapter08_09/solutions/templates/app/views/layouts/application.html.erb +20 -0
  97. data/lib/generators/chapter10/begin/USAGE +24 -0
  98. data/lib/generators/chapter10/begin/begin_generator.rb +41 -0
  99. data/lib/generators/chapter10/begin/instructions.md +47 -0
  100. data/lib/generators/chapter10/begin/snippets/custom.css +12 -0
  101. data/lib/generators/chapter10/begin/snippets/factories.rb +10 -0
  102. data/lib/generators/chapter10/begin/templates/app/views/layouts/application.html.erb +21 -0
  103. data/lib/generators/chapter10/begin/templates/lib/tasks/sample_data.rake +24 -0
  104. data/lib/generators/chapter10/begin/templates/spec/controllers/users_controller_10_spec.rb +110 -0
  105. data/lib/generators/chapter10/begin/templates/spec/models/user_10_spec.rb +24 -0
  106. data/lib/generators/chapter10/solutions/USAGE +18 -0
  107. data/lib/generators/chapter10/solutions/snippets/migration_add_admin_to_users.rb +9 -0
  108. data/lib/generators/chapter10/solutions/solutions_generator.rb +32 -0
  109. data/lib/generators/chapter10/solutions/templates/app/controllers/users_controller.rb +28 -0
  110. data/lib/generators/chapter10/solutions/templates/app/views/users/_user.html.erb +8 -0
  111. data/lib/generators/chapter10/solutions/templates/app/views/users/index.html.erb +9 -0
  112. data/lib/generators/chapter11_1/begin/USAGE +24 -0
  113. data/lib/generators/chapter11_1/begin/begin_generator.rb +24 -0
  114. data/lib/generators/chapter11_1/begin/instructions.md +39 -0
  115. data/lib/generators/chapter11_1/begin/templates/lib/tasks/sample_data.rake +29 -0
  116. data/lib/generators/chapter11_1/begin/templates/spec/models/microposts_11_1_spec.rb +45 -0
  117. data/lib/generators/chapter11_1/begin/templates/spec/models/user_11_1_spec.rb +30 -0
  118. data/lib/generators/chapter11_1/solutions/USAGE +18 -0
  119. data/lib/generators/chapter11_1/solutions/snippets/migration_create_microposts.rb +17 -0
  120. data/lib/generators/chapter11_1/solutions/solutions_generator.rb +25 -0
  121. data/lib/generators/chapter11_1/solutions/templates/app/models/micropost.rb +10 -0
  122. data/lib/generators/chapter11_1/solutions/templates/app/models/user.rb +14 -0
  123. data/lib/generators/chapter11_1/solutions/templates/spec/factories.rb +16 -0
  124. data/lib/generators/chapter11_2/begin/USAGE +24 -0
  125. data/lib/generators/chapter11_2/begin/begin_generator.rb +30 -0
  126. data/lib/generators/chapter11_2/begin/instructions.md +35 -0
  127. data/lib/generators/chapter11_2/begin/snippets/custom.css +59 -0
  128. data/lib/generators/chapter11_2/begin/templates/app/views/users/show.html.erb +23 -0
  129. data/lib/generators/chapter11_2/begin/templates/spec/controllers/users_controller_11_2_spec.rb +31 -0
  130. data/lib/generators/chapter11_2/solutions/USAGE +18 -0
  131. data/lib/generators/chapter11_2/solutions/solutions_generator.rb +12 -0
  132. data/lib/generators/chapter11_2/solutions/templates/app/controllers/users_controller.rb +29 -0
  133. data/lib/generators/chapter11_2/solutions/templates/app/views/microposts/_micropost.html.erb +8 -0
  134. data/lib/generators/chapter11_2/solutions/templates/app/views/users/show.html.erb +23 -0
  135. data/lib/generators/chapter11_3/begin/USAGE +24 -0
  136. data/lib/generators/chapter11_3/begin/begin_generator.rb +24 -0
  137. data/lib/generators/chapter11_3/begin/instructions.md +80 -0
  138. data/lib/generators/chapter11_3/begin/templates/app/views/pages/home.html.erb +24 -0
  139. data/lib/generators/chapter11_3/begin/templates/app/views/shared/_feed.html.erb +6 -0
  140. data/lib/generators/chapter11_3/begin/templates/app/views/shared/_feed_item.html.erb +14 -0
  141. data/lib/generators/chapter11_3/begin/templates/app/views/shared/_micropost_form.html.erb +9 -0
  142. data/lib/generators/chapter11_3/begin/templates/app/views/shared/_user_info.html.erb +11 -0
  143. data/lib/generators/chapter11_3/begin/templates/spec/controllers/microposts_controllers_11_3_spec.rb +103 -0
  144. data/lib/generators/chapter11_3/begin/templates/spec/controllers/pages_controller_11_3_spec.rb +14 -0
  145. data/lib/generators/chapter11_3/begin/templates/spec/models/user_11_3_spec.rb +31 -0
  146. data/lib/generators/chapter11_3/begin/templates/spec/requests/micropost_11_3_spec.rb +41 -0
  147. data/lib/generators/chapter11_3/solutions/USAGE +18 -0
  148. data/lib/generators/chapter11_3/solutions/solutions_generator.rb +30 -0
  149. data/lib/generators/chapter11_3/solutions/templates/app/controllers/microposts_controller.rb +20 -0
  150. data/lib/generators/chapter11_3/solutions/templates/app/controllers/pages_controller.rb +22 -0
  151. data/lib/generators/chapter11_3/solutions/templates/app/views/microposts/_micropost.html.erb +15 -0
  152. data/lib/generators/chapter11_3/solutions/templates/app/views/pages/home.html.erb +24 -0
  153. data/lib/generators/chapter11_3/solutions/templates/app/views/shared/_error_messages.html.erb +13 -0
  154. data/lib/generators/chapter11_3/solutions/templates/app/views/shared/_feed.html.erb +6 -0
  155. data/lib/generators/chapter11_3/solutions/templates/app/views/shared/_feed_item.html.erb +21 -0
  156. data/lib/generators/chapter11_3/solutions/templates/app/views/shared/_micropost_form.html.erb +9 -0
  157. data/lib/generators/chapter11_3/solutions/templates/app/views/shared/_user_info.html.erb +11 -0
  158. data/lib/tft_rails.rb +2 -0
  159. metadata +217 -0
@@ -0,0 +1,59 @@
1
+
2
+ /************************/
3
+ /* Through Chapter 11.2 */
4
+ /************************/
5
+
6
+ h1.micropost {
7
+ margin-bottom: 0.3em;
8
+ }
9
+
10
+ table.microposts {
11
+ margin-top: 1em;
12
+ }
13
+
14
+ table.microposts tr {
15
+ height: 70px;
16
+ }
17
+
18
+ table.microposts tr td.gravatar {
19
+ border-top: 1px solid #ccc;
20
+ vertical-align: top;
21
+ width: 50px;
22
+ }
23
+
24
+ table.microposts tr td.micropost {
25
+ border-top: 1px solid #ccc;
26
+ vertical-align: top;
27
+ padding-top: 10px;
28
+ }
29
+
30
+ table.microposts tr td.micropost span.timestamp {
31
+ display: block;
32
+ font-size: 85%;
33
+ color: #666;
34
+ }
35
+
36
+ div.user_info img {
37
+ padding-right: 0.1em;
38
+ }
39
+
40
+ div.user_info a {
41
+ text-decoration: none;
42
+ }
43
+
44
+ div.user_info span.user_name {
45
+ position: absolute;
46
+ }
47
+
48
+ div.user_info span.microposts {
49
+ font-size: 80%;
50
+ }
51
+
52
+ form.new_micropost {
53
+ margin-bottom: 2em;
54
+ }
55
+
56
+ form.new_micropost textarea {
57
+ height: 4em;
58
+ margin-bottom: 0;
59
+ }
@@ -0,0 +1,23 @@
1
+ <table class="profile" summary="Profile information">
2
+ <tr>
3
+ <td class="main">
4
+ <h1>
5
+ <%= gravatar_for @user %>
6
+ <%= @user.name %>
7
+ </h1>
8
+ <%# only if microposts exist, should the content below be rendered %>
9
+ <table class="microposts" summary="User microposts">
10
+ (The list of microposts should show up here, if there are any.)
11
+ </table>
12
+ <!--<%#= (pagination here, optional) %>-->
13
+ <%# end %>
14
+ </td>
15
+ <td class="sidebar round">
16
+ <strong>Name</strong> <%= @user.name %>
17
+ <br/>
18
+ <strong>URL</strong> <%= link_to user_path(@user.id), @user %>
19
+ <br/>
20
+ <strong>Microposts</strong> (The total count of Microposts should be here.)
21
+ </td>
22
+ </tr>
23
+ </table>
@@ -0,0 +1,31 @@
1
+ require 'spec_helper'
2
+
3
+ describe UsersController do
4
+
5
+ describe "GET 'show'" do
6
+
7
+ before(:each) do
8
+ @user = Factory(:user)
9
+ @mp1 = Factory(:micropost, :user => @user, :content => "Foo bar", :created_at => 1.day.ago)
10
+ @mp2 = Factory(:micropost, :user => @user, :content => "Baz quux",:created_at => 2.days.ago)
11
+ end
12
+
13
+ it 'should populate the @microposts instance variable' do
14
+ get :show, :id => @user.id
15
+ # Note: in a controller test, we can access instance variables
16
+ # of the controller by using the assigns[] function
17
+ assigns[:microposts].should == [@mp1,@mp2]
18
+ end
19
+
20
+ describe "HTML output" do
21
+ render_views
22
+
23
+ it "should show the user's microposts" do
24
+ get :show, :id => @user.id
25
+ response.should have_selector("span.content", :content => @mp1.content)
26
+ response.should have_selector("span.content", :content => @mp2.content)
27
+ end
28
+ end
29
+ end
30
+
31
+ end
@@ -0,0 +1,18 @@
1
+ Description:
2
+ Wraps up Test-First Teaching exercises adapted from Chapter 11.2 of the RailsTutorial by Michael Hartl.
3
+
4
+ Example:
5
+ rails generate chapter11:solutions
6
+
7
+ This copies the solutions and other necessary files (e.g. images, assets, helpers, etc.) into the project
8
+ to conclude Chapter 11.2. This should make all tests pass and bring you in sync to the application at
9
+ the end of Chapter 11.2.
10
+
11
+ If you already have a solution file, you'll be prompted whether you want to overwrite your file,
12
+ see the difference, or keep your file.
13
+
14
+ It's a good idea to commit your changes to git, prior to running finish, in case you accidentally choose to
15
+ overwrite files you wanted to keep. Assuming your project is already git-controlled, you can commit changes with:
16
+
17
+ git add .
18
+ git commit -m "comment here explaining WHY you made the changes"
@@ -0,0 +1,12 @@
1
+ module Chapter11_2
2
+ module Generators
3
+ class SolutionsGenerator < Rails::Generators::Base
4
+ source_root File.expand_path("../templates", __FILE__)
5
+
6
+ def copy_app_tree
7
+ directory(self.class.source_root, Rails.root)
8
+ end
9
+
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,29 @@
1
+ class UsersController < ApplicationController
2
+
3
+ before_filter :authenticate_user!, :only => [:index, :destroy]
4
+ before_filter :admin_user, :only => :destroy
5
+
6
+ def show
7
+ @user = User.find(params[:id])
8
+ @microposts = @user.microposts.paginate(:page => params[:page])
9
+ @title = @user.name
10
+ end
11
+
12
+ def index
13
+ @title = "All users"
14
+ @users = User.paginate(:page => params[:page])
15
+ end
16
+
17
+ def destroy
18
+ User.find(params[:id]).destroy
19
+ flash[:notice] = "User destroyed."
20
+ redirect_to users_path
21
+ end
22
+
23
+ private
24
+
25
+ def admin_user
26
+ redirect_to(root_path) unless current_user.admin?
27
+ end
28
+
29
+ end
@@ -0,0 +1,8 @@
1
+ <tr>
2
+ <td class="micropost">
3
+ <span class="content"><%= micropost.content %></span>
4
+ <span class="timestamp">
5
+ Posted <%= time_ago_in_words(micropost.created_at) %> ago.
6
+ </span>
7
+ </td>
8
+ </tr>
@@ -0,0 +1,23 @@
1
+ <table class="profile" summary="Profile information">
2
+ <tr>
3
+ <td class="main">
4
+ <h1>
5
+ <%= gravatar_for @user %>
6
+ <%= @user.name %>
7
+ </h1>
8
+ <% unless @user.microposts.empty? %>
9
+ <table class="microposts" summary="User microposts">
10
+ <%= render @microposts %>
11
+ </table>
12
+ <%= will_paginate @microposts %>
13
+ <% end %>
14
+ </td>
15
+ <td class="sidebar round">
16
+ <strong>Name</strong> <%= @user.name %>
17
+ <br/>
18
+ <strong>URL</strong> <%= link_to user_path(@user.id), @user %>
19
+ <br/>
20
+ <strong>Microposts</strong> <%= @user.microposts.count %>
21
+ </td>
22
+ </tr>
23
+ </table>
@@ -0,0 +1,24 @@
1
+ Description:
2
+ Begins Test-First Teaching exercises adapted from Chapter 11 of the RailsTutorial by Michael Hartl.
3
+
4
+ It is assumed that this generator is run after the exercises for Chapter 10 and all prior ones have been completed, and the solutions are implemented.
5
+
6
+ Successive chapters are expected to be run sequentially. Each chapter's generators comes with a delta
7
+ to the next chapter, in two phase, the "begin" one will create tests, the "finish" one includes the solution files.
8
+ If all tests pass, the "finish" phase is optional.
9
+
10
+ Example:
11
+ rails generate chapter11:begin
12
+
13
+ This copies new tests into the project, which are failing.
14
+ The student's task is to write code to make the test pass. The material covered by the tests is consistent
15
+ with Chapter 11 of the RailsTutorial, however adapted for Devise as authentication solution.
16
+
17
+ When you're done, and all tests pass, or you just want to skip ahead, run:
18
+
19
+ rails generate chapter10:solutions
20
+
21
+ This will copy solutions files into the application tree. If you already have a solution file,
22
+ you'll be prompted whether you want to overwrite your file, see the difference, or keep your file.
23
+
24
+
@@ -0,0 +1,24 @@
1
+ module Chapter11_3
2
+ module Generators
3
+ class BeginGenerator < Rails::Generators::Base
4
+ source_root File.expand_path("../templates", __FILE__)
5
+
6
+ def copy_app_tree
7
+ directory(self.class.source_root, Rails.root)
8
+ end
9
+
10
+ def generate_instructions
11
+ require 'rdiscount'
12
+
13
+ instr_md = File.expand_path('../instructions.md',self.class.source_root)
14
+ return unless File.exists?(instr_md)
15
+ dest = File.join(Rails.root,'doc','chapter11_3.html')
16
+ copy_file(instr_md, dest, :force => true) do |content|
17
+ RDiscount.new(content).to_html
18
+ end
19
+ say_status('Note',"Now open file://#{dest} in your web browser for instructions", :cyan)
20
+ end
21
+
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,80 @@
1
+ RailsTutorial Chapter 11.3 Test-First Teaching Instructions
2
+ ===========================================================
3
+
4
+ Controller
5
+ ----------
6
+
7
+ In this sub-chapter we're adding controllers and views to create and delete
8
+ microposts.
9
+
10
+ When you first run `rake spec`, you'll get an error like below and no specs will execute.
11
+
12
+ uninitialized constant MicropostsController (NameError)
13
+
14
+ This is because we don't have this class defined yet. So, go ahead and create it using the rails generators:
15
+
16
+ _Note_: **Microposts is in plural here** (Rails convention for controllers).
17
+
18
+ rails g controller Microposts --controller-specs=false --view-specs=false --helper-specs=false
19
+
20
+ Note: The controller generatore (unlike the model generator), we can instruct to suppress
21
+ the spec files.
22
+
23
+ Routing
24
+ -------
25
+
26
+ The next error will have to do with routing. Add a resource route for microposts.
27
+ Consider which actions are needed, by checking what tests case exist and
28
+ by carefully reading the test failure messages.
29
+ Then use the `:only => [...]` option to restrict the routes generated.
30
+
31
+ Views
32
+ -----
33
+
34
+ The tests will fail then complaining of missing view templates. Before you
35
+ go on to create micropost view templates, view the design mock-up
36
+ in Rails Tutorial [Chapter 11.3.2][chapter_11_3_2]. What view template
37
+ should hold the form fields to entering a micropost? If not a micropost
38
+ view, how can we tell the controller to render another view?
39
+
40
+ For a reference on the view templates, check [Listing 11.27][listing_11_27],
41
+ [Listing 11.28][listing_11_28] and [Listing 11.29][listing_11_29]
42
+
43
+ Controller Actions
44
+ ------------------
45
+
46
+ Next you'll need to implement the controller actions. For `create` there
47
+ are two branches, one for when saving the new record succeeds, i.e.
48
+ when validations pass, and one for when it fails.
49
+
50
+ Also, review the test cases carefully and consider if any of the actions
51
+ are supposed to be access controlled. Some test failures may look a bit
52
+ obscure when access control is not implemented.
53
+
54
+ The `destroy` action needs to make sure that only the use who created
55
+ the post can also delete it. Consider using the association methods
56
+ to constrain the seach for microposts to the currently signed-in user.
57
+
58
+ Display
59
+ -------
60
+
61
+ Take a moment to think about how you could show the user's posts
62
+ on the home page. There is no test for this, take a stab at it with
63
+ the tools and knowledge you now have.
64
+
65
+ Rails Concepts Covered
66
+ ======================
67
+
68
+ * Using controller generator
69
+ * Resource routes
70
+ * Controller render method
71
+ * Difference render & redirect, also redirect_to :back
72
+ * Access control
73
+ * Accessing records through an association (Association Proxy Methods)
74
+ * Controller create/update action pattern: success/failure branches
75
+ * find_by_id vs. find
76
+
77
+ [chapter_11_3_2]: http://ruby.railstutorial.org/chapters/user-microposts#sec:creating_microposts "Chapter 11.3.2"
78
+ [listing_11_27]: http://ruby.railstutorial.org/chapters/user-microposts#code:microposts_home_page "Listing 11.27"
79
+ [listing_11_28]: http://ruby.railstutorial.org/chapters/user-microposts#code:micropost_form "Listing 11.28"
80
+ [listing_11_29]: http://ruby.railstutorial.org/chapters/user-microposts#code:user_info "Listing 11.29"
@@ -0,0 +1,24 @@
1
+ <% if signed_in? %>
2
+ <table class="front" summary="For signed-in users">
3
+ <tr>
4
+ <td class="main">
5
+ <h1 class="micropost">What's up?</h1>
6
+ <%#= micropost form %>
7
+ <%#= feed of microposts %>
8
+ </td>
9
+ <td class="sidebar round">
10
+ <%#= sidebar with user info (name, image link) %>
11
+ </td>
12
+ </tr>
13
+ </table>
14
+ <% else %>
15
+ <h1>Sample App</h1>
16
+
17
+ <p>
18
+ This is the home page for the
19
+ <a href="http://railstutorial.org/">Ruby on Rails Tutorial</a>
20
+ sample application.
21
+ </p>
22
+
23
+ <%= link_to "Sign up now!", signup_path, :class => "signup_button round" %>
24
+ <% end %>
@@ -0,0 +1,6 @@
1
+ <%# if there are feed items %>
2
+ <table class="microposts" summary="User microposts">
3
+ <%#= display feed items here %>
4
+ </table>
5
+ <%#= pagination ? %>
6
+ <%# end %>
@@ -0,0 +1,14 @@
1
+ <tr>
2
+ <td class="gravatar">
3
+ <%# image %>
4
+ </td>
5
+ <td class="micropost">
6
+ <span class="user">
7
+ <%#= link to user %>
8
+ </span>
9
+ <span class="content"><%#= content of feed entry (i.e. a micropost) %></span>
10
+ <span class="timestamp">
11
+ Posted <%#= posting time of micropost %> ago.
12
+ </span>
13
+ </td>
14
+ </tr>
@@ -0,0 +1,9 @@
1
+ <%#= form helper %>
2
+ <%#= error display %>
3
+ <div class="field">
4
+ <%#= content form field %>
5
+ </div>
6
+ <div class="actions">
7
+ <%#= submit button %>
8
+ </div>
9
+ <%# end %>
@@ -0,0 +1,11 @@
1
+ <div class="user_info">
2
+ <a href="<%#= link to user %>">
3
+ <%#= user's image %>
4
+ <span class="user_name">
5
+ <%#= user's name %>
6
+ </span>
7
+ <span class="microposts">
8
+ <%# number of user's microposts %>
9
+ </span>
10
+ </a>
11
+ </div>
@@ -0,0 +1,103 @@
1
+ require 'spec_helper'
2
+
3
+ describe MicropostsController do
4
+ render_views
5
+
6
+ describe "access control" do
7
+
8
+ it "should deny access to 'create'" do
9
+ post :create
10
+ response.should redirect_to(new_user_session_path)
11
+ end
12
+
13
+ it "should deny access to 'destroy'" do
14
+ delete :destroy, :id => 1
15
+ response.should redirect_to(new_user_session_path)
16
+ end
17
+ end
18
+
19
+ describe "POST 'create'" do
20
+
21
+ before(:each) do
22
+ @user = Factory(:user)
23
+ sign_in(@user)
24
+ end
25
+
26
+ describe "failure" do
27
+
28
+ before(:each) do
29
+ @attr = { :content => "" }
30
+ end
31
+
32
+ it "should not create a micropost" do
33
+ lambda do
34
+ post :create, :micropost => @attr
35
+ end.should_not change(Micropost, :count)
36
+ end
37
+
38
+ it "should render the home page" do
39
+ post :create, :micropost => @attr
40
+ response.should render_template('pages/home')
41
+ end
42
+ end
43
+
44
+ describe "success" do
45
+
46
+ before(:each) do
47
+ @attr = { :content => "Lorem ipsum" }
48
+ end
49
+
50
+ it "should create a micropost" do
51
+ lambda do
52
+ post :create, :micropost => @attr
53
+ end.should change(Micropost, :count).by(1)
54
+ end
55
+
56
+ it "should redirect to the home page" do
57
+ post :create, :micropost => @attr
58
+ response.should redirect_to(root_path)
59
+ end
60
+
61
+ it "should have a flash message" do
62
+ post :create, :micropost => @attr
63
+ flash[:success].should =~ /micropost created/i
64
+ end
65
+ end
66
+ end
67
+
68
+ describe "DELETE 'destroy'" do
69
+
70
+ describe "for an unauthorized user" do
71
+
72
+ before(:each) do
73
+ @user = Factory(:user)
74
+ wrong_user = Factory(:user, :email => Factory.next(:email))
75
+ sign_in(wrong_user)
76
+ @micropost = Factory(:micropost, :user => @user)
77
+ request.env["HTTP_REFERER"] = root_path
78
+ end
79
+
80
+ it "should deny access" do
81
+ delete :destroy, :id => @micropost
82
+ response.should redirect_to(root_path)
83
+ end
84
+ end
85
+
86
+ describe "for an authorized user" do
87
+
88
+ before(:each) do
89
+ @user = Factory(:user)
90
+ sign_in(@user)
91
+ @micropost = Factory(:micropost, :user => @user)
92
+ request.env["HTTP_REFERER"] = user_path(@user) # for redirect_to :back
93
+ end
94
+
95
+ it "should destroy the micropost" do
96
+ lambda do
97
+ delete :destroy, :id => @micropost
98
+ end.should change(Micropost, :count).by(-1)
99
+ end
100
+ end
101
+ end
102
+
103
+ end
@@ -0,0 +1,14 @@
1
+ require 'spec_helper'
2
+
3
+ describe PagesController do
4
+
5
+ before do
6
+ @user = Factory(:user)
7
+ sign_in @user
8
+ end
9
+
10
+ it 'home page should instantiate a new micropost instance' do
11
+ get :home
12
+ assigns[:micropost].should_not be_nil
13
+ end
14
+ end
@@ -0,0 +1,31 @@
1
+ require 'spec_helper'
2
+
3
+ describe User do
4
+
5
+ describe "micropost associations" do
6
+
7
+ before(:each) do
8
+ @user = Factory(:user)
9
+ @mp1 = Factory(:micropost, :user => @user, :created_at => 1.day.ago)
10
+ @mp2 = Factory(:micropost, :user => @user, :created_at => 1.hour.ago)
11
+ end
12
+
13
+ describe "status feed" do
14
+
15
+ it "should have a feed" do
16
+ @user.should respond_to(:feed)
17
+ end
18
+
19
+ it "should include the user's microposts" do
20
+ @user.feed.include?(@mp1).should be_true
21
+ @user.feed.include?(@mp2).should be_true
22
+ end
23
+
24
+ it "should not include a different user's microposts" do
25
+ mp3 = Factory(:micropost,
26
+ :user => Factory(:user, :email => Factory.next(:email)))
27
+ @user.feed.include?(mp3).should be_false
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,41 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Microposts" do
4
+
5
+ before(:each) do
6
+ user = Factory(:user)
7
+ visit signin_path
8
+ fill_in :email, :with => user.email
9
+ fill_in :password, :with => user.password
10
+ click_button
11
+ end
12
+
13
+ describe "creation" do
14
+
15
+ describe "failure" do
16
+
17
+ it "should not make a new micropost" do
18
+ lambda do
19
+ visit root_path
20
+ fill_in :micropost_content, :with => ""
21
+ click_button
22
+ response.should render_template('pages/home')
23
+ response.should have_selector("div#error_explanation")
24
+ end.should_not change(Micropost, :count)
25
+ end
26
+ end
27
+
28
+ describe "success" do
29
+
30
+ it "should make a new micropost" do
31
+ content = "Lorem ipsum dolor sit amet"
32
+ lambda do
33
+ visit root_path
34
+ fill_in :micropost_content, :with => content
35
+ click_button
36
+ response.should have_selector("span.content", :content => content)
37
+ end.should change(Micropost, :count).by(1)
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,18 @@
1
+ Description:
2
+ Wraps up Test-First Teaching exercises adapted from Chapter 10 of the RailsTutorial by Michael Hartl.
3
+
4
+ Example:
5
+ rails generate chapter11:solutions
6
+
7
+ This copies the solutions and other necessary files (e.g. images, assets, helpers, etc.) into the project
8
+ to conclude Chapter 11. This should make all tests pass and bring you in sync to the application at
9
+ the end of Chapter 11.
10
+
11
+ If you already have a solution file, you'll be prompted whether you want to overwrite your file,
12
+ see the difference, or keep your file.
13
+
14
+ It's a good idea to commit your changes to git, prior to running finish, in case you accidentally choose to
15
+ overwrite files you wanted to keep. Assuming your project is already git-controlled, you can commit changes with:
16
+
17
+ git add .
18
+ git commit -m "comment here explaining WHY you made the changes"
@@ -0,0 +1,30 @@
1
+ module Chapter11_3
2
+ module Generators
3
+ class SolutionsGenerator < Rails::Generators::Base
4
+ source_root File.expand_path("../templates", __FILE__)
5
+
6
+ def copy_app_tree
7
+ directory(self.class.source_root, Rails.root)
8
+ end
9
+
10
+ def add_microposts_resource
11
+ dest = File.join(Rails.root,'config','routes.rb')
12
+ insert_into_file(dest, :after => %r{resources\s+:users.*$}) do
13
+ "\n resources :microposts, :only => [:create, :destroy]"
14
+ end
15
+ end
16
+
17
+ def add_feed_method_to_user
18
+ dest = File.join(Rails.root, 'app', 'models', 'user.rb')
19
+ insert_into_file(dest, :before => /end\s*\Z/) do # insert before end
20
+ <<-CODE.gsub(/^\s+\|/,' ')
21
+ |def feed
22
+ | microposts
23
+ |end
24
+ CODE
25
+ end
26
+ end
27
+
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,20 @@
1
+ class MicropostsController < ApplicationController
2
+ before_filter :authenticate_user!
3
+
4
+ def create
5
+ @micropost = current_user.microposts.build(params[:micropost])
6
+ if @micropost.save
7
+ flash[:success] = "Micropost created!"
8
+ redirect_to root_path
9
+ else
10
+ render 'pages/home'
11
+ end
12
+ end
13
+
14
+ def destroy
15
+ # .try will call the method given, unless the caller is nil
16
+ current_user.microposts.find_by_id(params[:id]).try(:destroy)
17
+ redirect_to :back
18
+ end
19
+
20
+ end