wbzyl-rails3-tutorial 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/README.markdown +14 -0
- data/Rakefile +34 -0
- data/TODO +6 -0
- data/VERSION.yml +4 -0
- data/config.ru +15 -0
- data/lib/config.ru +12 -0
- data/lib/public/images/bradypus.jpg +0 -0
- data/lib/public/images/leniwce_controller.png +0 -0
- data/lib/public/images/leniwce_controller.svg +284 -0
- data/lib/public/images/leniwiec.png +0 -0
- data/lib/public/images/leniwiec.svg +284 -0
- data/lib/public/images/mvc.png +0 -0
- data/lib/public/images/mvc.svg +243 -0
- data/lib/public/images/pablo_picasso.jpg +0 -0
- data/lib/public/images/pastie.png +0 -0
- data/lib/public/images/rails3.png +0 -0
- data/lib/public/images/rails3.svg +125 -0
- data/lib/public/images/the_thinker.jpg +0 -0
- data/lib/public/javascripts/ruby3.js +1 -0
- data/lib/public/stylesheets/icons/doc.png +0 -0
- data/lib/public/stylesheets/icons/email.png +0 -0
- data/lib/public/stylesheets/icons/external.png +0 -0
- data/lib/public/stylesheets/icons/feed.png +0 -0
- data/lib/public/stylesheets/icons/im.png +0 -0
- data/lib/public/stylesheets/icons/pdf.png +0 -0
- data/lib/public/stylesheets/icons/visited.png +0 -0
- data/lib/public/stylesheets/icons/xls.png +0 -0
- data/lib/public/stylesheets/ie.css +27 -0
- data/lib/public/stylesheets/print.css +30 -0
- data/lib/public/stylesheets/rails3.css +139 -0
- data/lib/public/stylesheets/screen.css +249 -0
- data/lib/public/stylesheets/src/grid.png +0 -0
- data/lib/public/stylesheets/uv.css +121 -0
- data/lib/rails3-tutorial.rb +72 -0
- data/lib/views/answers.rdiscount +0 -0
- data/lib/views/authentication.rdiscount +10 -0
- data/lib/views/blog.rdiscount +365 -0
- data/lib/views/caching.rdiscount +4 -0
- data/lib/views/exercises.rdiscount +67 -0
- data/lib/views/fortune.rdiscount +592 -0
- data/lib/views/intro.rdiscount +68 -0
- data/lib/views/layout.rdiscount +38 -0
- data/lib/views/main.rdiscount +32 -0
- data/lib/views/pastie.rdiscount +371 -0
- data/lib/views/store.rdiscount +99 -0
- data/lib/views/todo.rdiscount +245 -0
- data/rails3-tutorial.gemspec +101 -0
- metadata +168 -0
@@ -0,0 +1,72 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
# Zobacz przykład: http://gist.github.com/38605
|
4
|
+
|
5
|
+
gem 'rdiscount'
|
6
|
+
gem 'sinatra'
|
7
|
+
gem 'wbzyl-sinatra-rdiscount'
|
8
|
+
|
9
|
+
gem 'emk-sinatra-url-for'
|
10
|
+
gem 'wbzyl-sinatra-static-assets'
|
11
|
+
|
12
|
+
require 'rdiscount'
|
13
|
+
require 'sinatra/base'
|
14
|
+
require 'sinatra/rdiscount'
|
15
|
+
|
16
|
+
require 'sinatra/url_for'
|
17
|
+
require 'sinatra/static_assets'
|
18
|
+
|
19
|
+
module WB
|
20
|
+
class Rails3Tutorial < Sinatra::Base
|
21
|
+
helpers Sinatra::UrlForHelper
|
22
|
+
helpers Sinatra::StaticAssets
|
23
|
+
|
24
|
+
# disable overriding public and views dirs
|
25
|
+
set :app_file, __FILE__
|
26
|
+
set :static, true
|
27
|
+
|
28
|
+
# the middleware stack can be used internally as well. I'm using it for
|
29
|
+
# sessions, logging, and methodoverride. This lets us move stuff out of
|
30
|
+
# Sinatra if it's better handled by a middleware component.
|
31
|
+
set :logging, true # use Rack::CommonLogger
|
32
|
+
|
33
|
+
helpers Sinatra::RDiscount
|
34
|
+
|
35
|
+
# configure blocks:
|
36
|
+
# configure :production do
|
37
|
+
# end
|
38
|
+
|
39
|
+
#before do
|
40
|
+
# mime :sql, 'text/plain; charset="UTF-8"' # when served by Sinatra itself
|
41
|
+
#end
|
42
|
+
|
43
|
+
# helper methods
|
44
|
+
# attr_accessor :title
|
45
|
+
|
46
|
+
def title(name=nil)
|
47
|
+
@title = "WB/Rails3"
|
48
|
+
if name
|
49
|
+
@title += " | " + name.to_s
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
|
54
|
+
get '/' do
|
55
|
+
rdiscount :main
|
56
|
+
end
|
57
|
+
|
58
|
+
get '/:section' do
|
59
|
+
rdiscount :"#{params[:section]}"
|
60
|
+
end
|
61
|
+
|
62
|
+
error do
|
63
|
+
e = request.env['sinatra.error']
|
64
|
+
Kernel.puts e.backtrace.join("\n")
|
65
|
+
'Application error'
|
66
|
+
end
|
67
|
+
|
68
|
+
# each Sinatra::Base subclass has its own private middleware stack:
|
69
|
+
# use Rack::Lint
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
File without changes
|
@@ -0,0 +1,10 @@
|
|
1
|
+
#### {% title "Autentykacja" %}
|
2
|
+
|
3
|
+
Omówić: Ben Johnsos, [Authlogic](http://github.com/binarylogic/authlogic/).
|
4
|
+
A clean, simple, and unobtrusive ruby authentication solution.
|
5
|
+
|
6
|
+
Przykład jest tutaj:
|
7
|
+
[Authlogic Example](http://github.com/binarylogic/authlogic_example/).
|
8
|
+
|
9
|
+
Coś prostszego:
|
10
|
+
[Railscasts Screencast \#160: Authlogic](http://railscasts.com/episodes/160-authlogic)
|
@@ -0,0 +1,365 @@
|
|
1
|
+
#### {% title "Blog" %}
|
2
|
+
|
3
|
+
# Aplikacja: Blog
|
4
|
+
|
5
|
+
Lista aplikacji implementujących blog:
|
6
|
+
|
7
|
+
* A ruby on rails blogging app forr the fashionable developer:
|
8
|
+
[Enki](http://www.enkiblog.com/)
|
9
|
+
|
10
|
+
Aplikacja jest wykorzystywana w screencastach
|
11
|
+
R. Batesa. Repozytorium do ściągnięcia z Githuba:
|
12
|
+
|
13
|
+
git://github.com/ryanb/railscasts-episodes.git
|
14
|
+
cd railscasts-episodes/templates/blog
|
15
|
+
|
16
|
+
Katalog: *app*:
|
17
|
+
|
18
|
+
|-- app
|
19
|
+
| |-- controllers
|
20
|
+
| | |-- application_controller.rb
|
21
|
+
| | |-- articles_controller.rb
|
22
|
+
| | `-- comments_controller.rb
|
23
|
+
| |-- helpers
|
24
|
+
| | |-- application_helper.rb
|
25
|
+
| | |-- articles_helper.rb
|
26
|
+
| | |-- comments_helper.rb
|
27
|
+
| | `-- layout_helper.rb
|
28
|
+
| |-- models
|
29
|
+
| | |-- article.rb
|
30
|
+
| | `-- comment.rb
|
31
|
+
| `-- views
|
32
|
+
| |-- articles
|
33
|
+
| | |-- _form.html.erb
|
34
|
+
| | |-- edit.html.erb
|
35
|
+
| | |-- index.html.erb
|
36
|
+
| | |-- new.html.erb
|
37
|
+
| | `-- show.html.erb
|
38
|
+
| |-- comments
|
39
|
+
| | |-- _form.html.erb
|
40
|
+
| | |-- edit.html.erb
|
41
|
+
| | `-- new.html.erb
|
42
|
+
| `-- layouts
|
43
|
+
| `-- application.html.erb
|
44
|
+
|-- config
|
45
|
+
| |-- boot.rb
|
46
|
+
| |-- database.yml
|
47
|
+
| |-- environment.rb
|
48
|
+
| |-- environments
|
49
|
+
| | |-- development.rb
|
50
|
+
| | |-- production.rb
|
51
|
+
| | `-- test.rb
|
52
|
+
| |-- initializers
|
53
|
+
| | |-- inflections.rb
|
54
|
+
| | |-- mime_types.rb
|
55
|
+
| | `-- new_rails_defaults.rb
|
56
|
+
| `-- routes.rb
|
57
|
+
|-- db
|
58
|
+
| |-- migrate
|
59
|
+
| | |-- 20080719200447_create_articles.rb
|
60
|
+
| | `-- 20080719201435_create_comments.rb
|
61
|
+
| `-- schema.rb
|
62
|
+
|-- lib
|
63
|
+
| `-- tasks
|
64
|
+
| `-- application.rake
|
65
|
+
|-- public
|
66
|
+
| |-- 404.html
|
67
|
+
| |-- 422.html
|
68
|
+
| |-- 500.html
|
69
|
+
.
|
70
|
+
.
|
71
|
+
26 directories, 70 files
|
72
|
+
|
73
|
+
Tak jak w wypadku aplikacji TODO powinniśmy zacząć od przyjrzenia
|
74
|
+
się migracjom. Ale prościej będzie obejrzeć plik *schema.rb*:
|
75
|
+
|
76
|
+
:::ruby
|
77
|
+
# This file is auto-generated from the current state of the database.
|
78
|
+
# Note that this schema.rb definition is the authoritative source for
|
79
|
+
# your database schema. If you need to create the application database
|
80
|
+
# on another system, you should be using db:schema:load, not running
|
81
|
+
# all the migrations from scratch. The latter is a flawed and
|
82
|
+
# unsustainable approach (the more migrations you'll amass, the slower
|
83
|
+
# it'll run and the greater likelihood for issues). It's strongly
|
84
|
+
# recommended to check this file into your version control system.
|
85
|
+
|
86
|
+
ActiveRecord::Schema.define(:version => 20080719201435) do
|
87
|
+
|
88
|
+
create_table "articles", :force => true do |t|
|
89
|
+
t.string "name"
|
90
|
+
t.text "content"
|
91
|
+
t.string "author_name"
|
92
|
+
t.datetime "created_at"
|
93
|
+
t.datetime "updated_at"
|
94
|
+
end
|
95
|
+
|
96
|
+
create_table "comments", :force => true do |t|
|
97
|
+
t.integer "article_id"
|
98
|
+
t.string "author_name"
|
99
|
+
t.string "site_url"
|
100
|
+
t.text "content"
|
101
|
+
t.datetime "created_at"
|
102
|
+
t.datetime "updated_at"
|
103
|
+
end
|
104
|
+
|
105
|
+
end
|
106
|
+
|
107
|
+
I definicjom modeli:
|
108
|
+
|
109
|
+
:::ruby
|
110
|
+
class Article < ActiveRecord::Base
|
111
|
+
has_many :comments, :dependent => :destroy
|
112
|
+
validates_presence_of :name, :content
|
113
|
+
end
|
114
|
+
|
115
|
+
class Comment < ActiveRecord::Base
|
116
|
+
belongs_to :article
|
117
|
+
validates_presence_of :author_name, :content
|
118
|
+
end
|
119
|
+
|
120
|
+
Teraz kolej na routing:
|
121
|
+
|
122
|
+
:::ruby
|
123
|
+
ActionController::Routing::Routes.draw do |map|
|
124
|
+
map.resources :articles, :comments
|
125
|
+
map.root :articles
|
126
|
+
end
|
127
|
+
|
128
|
+
Teraz już możemy się przyjrzeć aplikacji:
|
129
|
+
|
130
|
+
rake db:create
|
131
|
+
rake db:migrate
|
132
|
+
|
133
|
+
Jeszcze dla przypomnienia:
|
134
|
+
|
135
|
+
rake routes
|
136
|
+
|
137
|
+
i uruchamiamy aplikację:
|
138
|
+
|
139
|
+
script/server thin -p 3000
|
140
|
+
|
141
|
+
|
142
|
+
## Kontrolery
|
143
|
+
|
144
|
+
Kontroler *ArticlesController*:
|
145
|
+
|
146
|
+
:::ruby
|
147
|
+
class ArticlesController < ApplicationController
|
148
|
+
def index
|
149
|
+
@articles = Article.find(:all)
|
150
|
+
end
|
151
|
+
|
152
|
+
# Ważne:
|
153
|
+
# w widoku show.html.erb możemy edytować komentarze
|
154
|
+
# do oglądanego artykułu
|
155
|
+
def show
|
156
|
+
@article = Article.find(params[:id])
|
157
|
+
@comment = Comment.new(:article => @article)
|
158
|
+
end
|
159
|
+
|
160
|
+
def new
|
161
|
+
@article = Article.new
|
162
|
+
end
|
163
|
+
|
164
|
+
def create
|
165
|
+
@article = Article.new(params[:article])
|
166
|
+
if @article.save
|
167
|
+
flash[:notice] = "Successfully created article."
|
168
|
+
redirect_to @article
|
169
|
+
else
|
170
|
+
render :action => 'new'
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
def edit
|
175
|
+
@article = Article.find(params[:id])
|
176
|
+
end
|
177
|
+
|
178
|
+
def update
|
179
|
+
@article = Article.find(params[:id])
|
180
|
+
if @article.update_attributes(params[:article])
|
181
|
+
flash[:notice] = "Successfully updated article."
|
182
|
+
redirect_to @article
|
183
|
+
else
|
184
|
+
render :action => 'edit'
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
def destroy
|
189
|
+
@article = Article.find(params[:id])
|
190
|
+
@article.destroy
|
191
|
+
flash[:notice] = "Successfully destroyed article."
|
192
|
+
redirect_to articles_url
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
196
|
+
Kontroler *CommentsController*.
|
197
|
+
Ten kontroler nie ma akcji *index* oraz *show*.
|
198
|
+
Dlaczego? Jeśli nie znasz odpowiedzi, oznacza to, że
|
199
|
+
za krótko „bawiłeś” się aplikacją.
|
200
|
+
|
201
|
+
:::ruby
|
202
|
+
class CommentsController < ApplicationController
|
203
|
+
# Metoda new nie jest używana w aplikacji.
|
204
|
+
# Prawda to czy fałsz?
|
205
|
+
def new
|
206
|
+
@comment = Comment.new
|
207
|
+
end
|
208
|
+
|
209
|
+
# Jak powiązać komentarz z artykułem?
|
210
|
+
# Zakładamy, że do metody został przekazany jakoś id artykułu.
|
211
|
+
# Jak?
|
212
|
+
def create
|
213
|
+
@comment = Comment.new(params[:comment])
|
214
|
+
if @comment.save
|
215
|
+
flash[:notice] = "Successfully created comment."
|
216
|
+
redirect_to article_url(@comment.article_id)
|
217
|
+
else
|
218
|
+
render :action => 'new'
|
219
|
+
end
|
220
|
+
end
|
221
|
+
|
222
|
+
def edit
|
223
|
+
@comment = Comment.find(params[:id])
|
224
|
+
end
|
225
|
+
|
226
|
+
# A jak tutaj jest przekazywany id artykułu?
|
227
|
+
def update
|
228
|
+
@comment = Comment.find(params[:id])
|
229
|
+
if @comment.update_attributes(params[:comment])
|
230
|
+
flash[:notice] = "Successfully updated comment."
|
231
|
+
redirect_to article_url(@comment.article_id)
|
232
|
+
else
|
233
|
+
render :action => 'edit'
|
234
|
+
end
|
235
|
+
end
|
236
|
+
|
237
|
+
# Metoda destroy nie jest używana w aplikacji.
|
238
|
+
# Prawda to czy fałsz?
|
239
|
+
def destroy
|
240
|
+
@comment = Comment.find(params[:id])
|
241
|
+
@comment.destroy
|
242
|
+
flash[:notice] = "Successfully destroyed comment."
|
243
|
+
redirect_to article_url(@comment.article_id)
|
244
|
+
end
|
245
|
+
end
|
246
|
+
|
247
|
+
## Widoki dla kontrolera *ArticlesController*
|
248
|
+
|
249
|
+
|
250
|
+
Widok *index.html.erb*:
|
251
|
+
|
252
|
+
:::xml
|
253
|
+
<% title "Articles" %>
|
254
|
+
|
255
|
+
<div id="articles">
|
256
|
+
<% for article in @articles %>
|
257
|
+
<h2>
|
258
|
+
<%= link_to h(article.name), article %>
|
259
|
+
<span class="comments">(<%= pluralize(article.comments.size, 'comment') %>)</span>
|
260
|
+
</h2>
|
261
|
+
<div class="author">from <%=h article.author_name %>
|
262
|
+
on <%= article.created_at.strftime('%b %d, %Y') %></div>
|
263
|
+
<div class="content"><%= simple_format(article.content) %></div>
|
264
|
+
<% end %>
|
265
|
+
</div>
|
266
|
+
|
267
|
+
Widok częściowy *_form.html.erb*:
|
268
|
+
|
269
|
+
:::xml
|
270
|
+
<%= error_messages_for :article %>
|
271
|
+
<% form_for @article do |f| %>
|
272
|
+
<p>
|
273
|
+
<%= f.label :name %><br />
|
274
|
+
<%= f.text_field :name %>
|
275
|
+
</p>
|
276
|
+
<p>
|
277
|
+
<%= f.label :content %><br />
|
278
|
+
<%= f.text_area :content %>
|
279
|
+
</p>
|
280
|
+
<p>
|
281
|
+
<%= f.label :author_name %><br />
|
282
|
+
<%= f.text_field :author_name %>
|
283
|
+
</p>
|
284
|
+
<p><%= f.submit "Submit" %></p>
|
285
|
+
<% end %>
|
286
|
+
|
287
|
+
Widok *show.html.erb*:
|
288
|
+
|
289
|
+
:::xml
|
290
|
+
<% title @article.name %>
|
291
|
+
|
292
|
+
<p class="author"><em>from <%=h @article.author_name %></em></p>
|
293
|
+
|
294
|
+
<%=simple_format @article.content %>
|
295
|
+
|
296
|
+
<p><%= link_to "Back to Articles", articles_path %></p>
|
297
|
+
|
298
|
+
<% unless @article.comments.empty? %>
|
299
|
+
<h2><%= pluralize(@article.comments.size, 'comment') %></h2>
|
300
|
+
|
301
|
+
<div id="comments">
|
302
|
+
<% for comment in @article.comments %>
|
303
|
+
<div class="comment">
|
304
|
+
<strong><%= link_to_unless comment.site_url.blank?,
|
305
|
+
h(comment.author_name), h(comment.site_url) %></strong>
|
306
|
+
<em>on <%= comment.created_at.strftime('%b %d, %Y at %H:%M') %></em>
|
307
|
+
<%=simple_format comment.content %>
|
308
|
+
</div>
|
309
|
+
<% end %>
|
310
|
+
</div>
|
311
|
+
<% end %>
|
312
|
+
|
313
|
+
<h3>Add your comment:</h3>
|
314
|
+
<%= render :partial => 'comments/form' %>
|
315
|
+
|
316
|
+
Widok częściowy *comments/_form.html.erb*:
|
317
|
+
|
318
|
+
:::xml
|
319
|
+
<%= error_messages_for :comment %>
|
320
|
+
<% form_for @comment do |f| %>
|
321
|
+
<%= f.hidden_field :article_id %>
|
322
|
+
<p>
|
323
|
+
<%= f.label :author_name, 'Name' %><br />
|
324
|
+
<%= f.text_field :author_name %>
|
325
|
+
</p>
|
326
|
+
<p>
|
327
|
+
<%= f.label :site_url, 'Website URL' %><br />
|
328
|
+
<%= f.text_field :site_url %>
|
329
|
+
</p>
|
330
|
+
<p>
|
331
|
+
<%= f.label :content, 'Comment' %><br />
|
332
|
+
<%= f.text_area :content, :rows => '12', :cols => 35 %>
|
333
|
+
</p>
|
334
|
+
<p><%= f.submit "Submit" %></p>
|
335
|
+
<% end %>
|
336
|
+
|
337
|
+
Widok *edit.html.erb*:
|
338
|
+
|
339
|
+
:::xml
|
340
|
+
<% title "Edit Article" %>
|
341
|
+
|
342
|
+
<%= render :partial => 'form' %>
|
343
|
+
|
344
|
+
<p>
|
345
|
+
<%= link_to "Show", @article %> |
|
346
|
+
<%= link_to "View All", articles_path %>
|
347
|
+
</p>
|
348
|
+
|
349
|
+
I na koniec, widok *new.html.erb*:
|
350
|
+
|
351
|
+
:::xml
|
352
|
+
<% title "New Article" %>
|
353
|
+
|
354
|
+
<%= render :partial => 'form' %>
|
355
|
+
|
356
|
+
<p><%= link_to "Back to List", articles_path %></p>
|
357
|
+
|
358
|
+
|
359
|
+
## Co jeszcze zostało do omówienia?
|
360
|
+
|
361
|
+
Gdzie można znaleźć definicję metody *simple_format*.
|
362
|
+
|
363
|
+
Jakie ciekawe metody zawiera *layout_helper.html.erb*?
|
364
|
+
|
365
|
+
Jakie pliki powinniśmy jeszcze obejrzeć?
|