wbzyl-rails3-tutorial 0.0.2
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.
- 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ć?
|