tft_rails 0.6.1 → 0.6.2
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +14 -0
- data/lib/generators/chapter07/begin/begin_generator.rb +7 -0
- data/lib/generators/chapter07/begin/templates/spec/spec_helper.rb +10 -0
- data/lib/generators/chapter08_09/begin/instructions.md +8 -1
- data/lib/generators/chapter10/begin/templates/lib/tasks/{same_data.rake → sample_data.rake} +0 -0
- data/lib/generators/chapter10/solutions/snippets/migration_add_admin_to_users.rb +1 -1
- data/lib/generators/chapter11_1/begin/templates/lib/tasks/{same_data.rake → sample_data.rake} +0 -0
- data/lib/generators/chapter11_1/solutions/templates/app/{model → models}/micropost.rb +1 -1
- data/lib/generators/chapter11_1/solutions/templates/app/{model → models}/user.rb +0 -0
- data/lib/generators/chapter11_2/solutions/solutions_generator.rb +6 -0
- data/lib/generators/chapter11_3/begin/templates/app/views/pages/home.html.erb +24 -0
- data/lib/generators/chapter11_3/begin/templates/app/views/shared/_feed.html.erb +6 -0
- data/lib/generators/chapter11_3/begin/templates/app/views/shared/_feed_item.html.erb +14 -0
- data/lib/generators/chapter11_3/begin/templates/app/views/shared/_micropost_form.html.erb +9 -0
- data/lib/generators/chapter11_3/begin/templates/app/views/shared/_user_info.html.erb +11 -0
- data/lib/generators/chapter11_3/begin/templates/spec/controllers/microposts_controllers_11_3_spec.rb +1 -0
- data/lib/generators/chapter11_3/begin/templates/spec/models/user_11_3_spec.rb +31 -0
- data/lib/generators/chapter11_3/begin/templates/spec/requests/micropost_11_3_spec.rb +41 -0
- data/lib/generators/chapter11_3/solutions/solutions_generator.rb +22 -0
- data/lib/generators/chapter11_3/solutions/templates/app/controllers/microposts_controller.rb +20 -0
- data/lib/generators/chapter11_3/solutions/templates/app/controllers/pages_controller.rb +22 -0
- data/lib/generators/chapter11_3/solutions/templates/app/views/microposts/_micropost.html.erb +15 -0
- data/lib/generators/chapter11_3/solutions/templates/app/views/pages/home.html.erb +24 -0
- data/lib/generators/chapter11_3/solutions/templates/app/views/shared/_error_messages.html.erb +13 -0
- data/lib/generators/chapter11_3/solutions/templates/app/views/shared/_feed.html.erb +6 -0
- data/lib/generators/chapter11_3/solutions/templates/app/views/shared/_feed_item.html.erb +21 -0
- data/lib/generators/chapter11_3/solutions/templates/app/views/shared/_micropost_form.html.erb +9 -0
- data/lib/generators/chapter11_3/solutions/templates/app/views/shared/_user_info.html.erb +11 -0
- metadata +22 -6
data/README.md
CHANGED
@@ -60,6 +60,20 @@ a wonderful job to illustrate many concepts for teaching, but it is no replaceme
|
|
60
60
|
that has been peer-reviewed by many experienced developers and is in use in many commercial applications. Devise is the
|
61
61
|
current industry standard solution and was used here.
|
62
62
|
|
63
|
+
Adding to TFT Rails
|
64
|
+
-------------------
|
65
|
+
|
66
|
+
To modify the exercises, make your code changes, then run all chapters in
|
67
|
+
successive order in a few rails app. After every solutions generator, the
|
68
|
+
specs should run clean.
|
69
|
+
|
70
|
+
TODO: Rig up a test suite which will create a new rails app, then install
|
71
|
+
all chapters and solutions in successive order and run the spec suite every time.
|
72
|
+
This may necessitate construction our own Test Runner or similar. I'm not
|
73
|
+
sure how to do this.
|
74
|
+
|
75
|
+
TODO: Add Chapter 12. The project currently contains Chapters 7 through 11, adapted for Devise.
|
76
|
+
|
63
77
|
Sponsors
|
64
78
|
--------
|
65
79
|
|
@@ -7,6 +7,13 @@ module Chapter07
|
|
7
7
|
directory(self.class.source_root, Rails.root, :force => true)
|
8
8
|
end
|
9
9
|
|
10
|
+
def insert_gitignore
|
11
|
+
dest = File.join(Rails.root,'.gitignore')
|
12
|
+
insert_into_file(dest, :before => /\Z/) do # insert before end
|
13
|
+
"\n.idea\n"
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
10
17
|
def augment_gemfile
|
11
18
|
gem 'devise', '~> 1.3.4'
|
12
19
|
gem 'gravatar_image_tag', '~> 1.0.0'
|
@@ -7,6 +7,16 @@ require 'rspec/rails'
|
|
7
7
|
# in spec/support/ and its subdirectories.
|
8
8
|
Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f}
|
9
9
|
|
10
|
+
Webrat.configure do |config|
|
11
|
+
config.mode = :rack
|
12
|
+
end
|
13
|
+
|
14
|
+
module Webrat::Logging
|
15
|
+
def logger
|
16
|
+
Rails.logger # log to test.log, rather than webrat.log
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
10
20
|
RSpec.configure do |config|
|
11
21
|
# == Mock Framework
|
12
22
|
#
|
@@ -50,9 +50,16 @@ The Devise sign-in page meets our needs and doesn't need customizing.
|
|
50
50
|
However, we need to work on the layout to make sure that it shows a "Sign out" link
|
51
51
|
if a user is logged in, and a "Sign in" link only if a user is not logged in.
|
52
52
|
|
53
|
-
[Devise][devise] offers the controller methods `
|
53
|
+
[Devise][devise] offers the controller methods `signed_in?` and `current_user`
|
54
54
|
to report on the current login status. The first method returns `true` or `false`
|
55
55
|
depending on whether a user logged in, the second returns the actual user object,
|
56
56
|
or `nil` if no user is logged in.
|
57
57
|
|
58
|
+
(Note that Devise supports multiple sign-in scopes, e.g. for regular users and
|
59
|
+
for admins. The method `signed_in?` checks that any scope is signed in. To
|
60
|
+
check for a specific scope, the method `user_signed_in?` is available. For the
|
61
|
+
purpose of RailsTutorial with Devise, this distinction is not important since
|
62
|
+
we only have one type of user. Admin privileges are implemented differently,
|
63
|
+
with the admin flag)
|
64
|
+
|
58
65
|
[devise]: https://github.com/plataformatec/devise "Devise on github"
|
File without changes
|
data/lib/generators/chapter11_1/begin/templates/lib/tasks/{same_data.rake → sample_data.rake}
RENAMED
File without changes
|
File without changes
|
@@ -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,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,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
|
@@ -1,7 +1,29 @@
|
|
1
1
|
module Chapter11_3
|
2
2
|
module Generators
|
3
3
|
class SolutionsGenerator < Rails::Generators::Base
|
4
|
+
source_root File.expand_path("../templates", __FILE__)
|
4
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
|
5
27
|
|
6
28
|
end
|
7
29
|
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
|
@@ -0,0 +1,22 @@
|
|
1
|
+
class PagesController < ApplicationController
|
2
|
+
def home
|
3
|
+
@title = "Home"
|
4
|
+
if signed_in?
|
5
|
+
@micropost = current_user.microposts.build
|
6
|
+
@feed_items = current_user.feed.paginate(:page => params[:page])
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
def contact
|
11
|
+
@title = 'Contact'
|
12
|
+
end
|
13
|
+
|
14
|
+
def about
|
15
|
+
@title = 'About'
|
16
|
+
end
|
17
|
+
|
18
|
+
def help
|
19
|
+
@title = 'Help'
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
@@ -0,0 +1,15 @@
|
|
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
|
+
<% if signed_in? && current_user.id == micropost.user_id %>
|
9
|
+
<td>
|
10
|
+
<%= link_to "delete", micropost, :method => :delete,
|
11
|
+
:confirm => "You sure?",
|
12
|
+
:title => micropost.content %>
|
13
|
+
</td>
|
14
|
+
<% end %>
|
15
|
+
</tr>
|
@@ -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
|
+
<%= render 'shared/micropost_form' %>
|
7
|
+
<%= render 'shared/feed' %>
|
8
|
+
</td>
|
9
|
+
<td class="sidebar round">
|
10
|
+
<%= render 'shared/user_info' %>
|
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,13 @@
|
|
1
|
+
<% if object.errors.any? %>
|
2
|
+
<div id="error_explanation">
|
3
|
+
<h2><%= pluralize(object.errors.count, "error") %>
|
4
|
+
prohibited this <%= object.class.to_s.underscore.humanize.downcase %>
|
5
|
+
from being saved:</h2>
|
6
|
+
<p>There were problems with the following fields:</p>
|
7
|
+
<ul>
|
8
|
+
<% object.errors.full_messages.each do |msg| %>
|
9
|
+
<li><%= msg %></li>
|
10
|
+
<% end %>
|
11
|
+
</ul>
|
12
|
+
</div>
|
13
|
+
<% end %>
|
@@ -0,0 +1,21 @@
|
|
1
|
+
<tr>
|
2
|
+
<td class="gravatar">
|
3
|
+
<%= link_to gravatar_for(feed_item.user), feed_item.user %>
|
4
|
+
</td>
|
5
|
+
<td class="micropost">
|
6
|
+
<span class="user">
|
7
|
+
<%= link_to feed_item.user.name, feed_item.user %>
|
8
|
+
</span>
|
9
|
+
<span class="content"><%= feed_item.content %></span>
|
10
|
+
<span class="timestamp">
|
11
|
+
Posted <%= time_ago_in_words(feed_item.created_at) %> ago.
|
12
|
+
</span>
|
13
|
+
</td>
|
14
|
+
<% if signed_in? && current_user.id == feed_item.user_id %>
|
15
|
+
<td>
|
16
|
+
<%= link_to "delete", feed_item, :method => :delete,
|
17
|
+
:confirm => "You sure?",
|
18
|
+
:title => feed_item.content %>
|
19
|
+
</td>
|
20
|
+
<% end %>
|
21
|
+
</tr>
|
@@ -0,0 +1,11 @@
|
|
1
|
+
<div class="user_info">
|
2
|
+
<a href="<%= user_path(current_user) %>">
|
3
|
+
<%= gravatar_for current_user, :size => 30 %>
|
4
|
+
<span class="user_name">
|
5
|
+
<%= current_user.name %>
|
6
|
+
</span>
|
7
|
+
<span class="microposts">
|
8
|
+
<%= pluralize(current_user.microposts.count, "micropost") %>
|
9
|
+
</span>
|
10
|
+
</a>
|
11
|
+
</div>
|
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: tft_rails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 0.6.
|
5
|
+
version: 0.6.2
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Wolfram Arnold
|
@@ -10,7 +10,7 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date: 2011-07-
|
13
|
+
date: 2011-07-25 00:00:00 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: rdiscount
|
@@ -38,8 +38,24 @@ files:
|
|
38
38
|
- lib/generators/chapter11_3/begin/instructions.md
|
39
39
|
- lib/generators/chapter11_3/begin/templates/spec/controllers/pages_controller_11_3_spec.rb
|
40
40
|
- lib/generators/chapter11_3/begin/templates/spec/controllers/microposts_controllers_11_3_spec.rb
|
41
|
+
- lib/generators/chapter11_3/begin/templates/spec/models/user_11_3_spec.rb
|
42
|
+
- lib/generators/chapter11_3/begin/templates/spec/requests/micropost_11_3_spec.rb
|
43
|
+
- lib/generators/chapter11_3/begin/templates/app/views/pages/home.html.erb
|
44
|
+
- lib/generators/chapter11_3/begin/templates/app/views/shared/_user_info.html.erb
|
45
|
+
- lib/generators/chapter11_3/begin/templates/app/views/shared/_micropost_form.html.erb
|
46
|
+
- lib/generators/chapter11_3/begin/templates/app/views/shared/_feed.html.erb
|
47
|
+
- lib/generators/chapter11_3/begin/templates/app/views/shared/_feed_item.html.erb
|
41
48
|
- lib/generators/chapter11_3/solutions/USAGE
|
42
49
|
- lib/generators/chapter11_3/solutions/solutions_generator.rb
|
50
|
+
- lib/generators/chapter11_3/solutions/templates/app/controllers/microposts_controller.rb
|
51
|
+
- lib/generators/chapter11_3/solutions/templates/app/controllers/pages_controller.rb
|
52
|
+
- lib/generators/chapter11_3/solutions/templates/app/views/pages/home.html.erb
|
53
|
+
- lib/generators/chapter11_3/solutions/templates/app/views/microposts/_micropost.html.erb
|
54
|
+
- lib/generators/chapter11_3/solutions/templates/app/views/shared/_user_info.html.erb
|
55
|
+
- lib/generators/chapter11_3/solutions/templates/app/views/shared/_error_messages.html.erb
|
56
|
+
- lib/generators/chapter11_3/solutions/templates/app/views/shared/_micropost_form.html.erb
|
57
|
+
- lib/generators/chapter11_3/solutions/templates/app/views/shared/_feed.html.erb
|
58
|
+
- lib/generators/chapter11_3/solutions/templates/app/views/shared/_feed_item.html.erb
|
43
59
|
- lib/generators/chapter07/begin/USAGE
|
44
60
|
- lib/generators/chapter07/begin/begin_generator.rb
|
45
61
|
- lib/generators/chapter07/begin/instructions.md
|
@@ -127,7 +143,7 @@ files:
|
|
127
143
|
- lib/generators/chapter10/begin/instructions.md
|
128
144
|
- lib/generators/chapter10/begin/snippets/custom.css
|
129
145
|
- lib/generators/chapter10/begin/snippets/factories.rb
|
130
|
-
- lib/generators/chapter10/begin/templates/lib/tasks/
|
146
|
+
- lib/generators/chapter10/begin/templates/lib/tasks/sample_data.rake
|
131
147
|
- lib/generators/chapter10/begin/templates/spec/controllers/users_controller_10_spec.rb
|
132
148
|
- lib/generators/chapter10/begin/templates/spec/models/user_10_spec.rb
|
133
149
|
- lib/generators/chapter10/begin/templates/app/views/layouts/application.html.erb
|
@@ -159,15 +175,15 @@ files:
|
|
159
175
|
- lib/generators/chapter11_1/begin/USAGE
|
160
176
|
- lib/generators/chapter11_1/begin/begin_generator.rb
|
161
177
|
- lib/generators/chapter11_1/begin/instructions.md
|
162
|
-
- lib/generators/chapter11_1/begin/templates/lib/tasks/
|
178
|
+
- lib/generators/chapter11_1/begin/templates/lib/tasks/sample_data.rake
|
163
179
|
- lib/generators/chapter11_1/begin/templates/spec/models/user_11_1_spec.rb
|
164
180
|
- lib/generators/chapter11_1/begin/templates/spec/models/microposts_11_1_spec.rb
|
165
181
|
- lib/generators/chapter11_1/solutions/USAGE
|
166
182
|
- lib/generators/chapter11_1/solutions/solutions_generator.rb
|
167
183
|
- lib/generators/chapter11_1/solutions/snippets/migration_create_microposts.rb
|
168
184
|
- lib/generators/chapter11_1/solutions/templates/spec/factories.rb
|
169
|
-
- lib/generators/chapter11_1/solutions/templates/app/
|
170
|
-
- lib/generators/chapter11_1/solutions/templates/app/
|
185
|
+
- lib/generators/chapter11_1/solutions/templates/app/models/user.rb
|
186
|
+
- lib/generators/chapter11_1/solutions/templates/app/models/micropost.rb
|
171
187
|
- LICENSE
|
172
188
|
- Rakefile
|
173
189
|
- Gemfile
|