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,67 @@
|
|
1
|
+
#### {% title "Ćwiczenia" %}
|
2
|
+
|
3
|
+
# Ćwiczenia
|
4
|
+
|
5
|
+
1\. Udoskonalamy „Fortunkę”:
|
6
|
+
|
7
|
+
* Utworzyć nową stronę główną aplikacji.
|
8
|
+
Umieścić na niej po jednym losowym cytacie
|
9
|
+
z każdej kategorii oraz linki do stron
|
10
|
+
z indeksami kategorii.
|
11
|
+
* Zaimplementować tagowanie obrazków tak jak to jest pokazane na screencaście
|
12
|
+
[More on Virtual Attributes](http://railscasts.com/episodes/167-more-on-virtual-attributes).
|
13
|
+
* Jeszcze raz otagować obrazki. Tym razem skorzystać z
|
14
|
+
[Acts As Taggable on Steroids Ruby On Rails Plugin With
|
15
|
+
Paginate](http://burm.net/2008/10/08/acts-as-taggable-on-steroids-ruby-on-rails-plugin-with-paginate/)
|
16
|
+
|
17
|
+
2\. Wystylizować „Leniwca z o.o.”.
|
18
|
+
|
19
|
+
Do strony z wynikami wyszukiwania dodać paginację.
|
20
|
+
Skorzystać z gemu
|
21
|
+
[mislav-will-paginate](http://github.com/mislav/will_paginate/).
|
22
|
+
|
23
|
+
Do wyszukiwarki dodać select-menu z listą języków
|
24
|
+
obsługiwanych przez gem *Ultraviolet*
|
25
|
+
(`uv -l syntaxes`). Zmodyfikować kod *leniwca.local*, tak aby
|
26
|
+
było możliwe wyszukiwanie fragmentów kodu z wybranego
|
27
|
+
języka. Wskazówka: objerzeć screencast
|
28
|
+
[Advanced Search Form](http://railscasts.com/episodes/111-advanced-search-form)
|
29
|
+
Uwaga: na liście języków umieścić „Wszystkie języki”,
|
30
|
+
„Języki skryptowe“ i „Języki kompilowane”.
|
31
|
+
|
32
|
+
Wpisać listę wszystkich języków do tabelki *languages*.
|
33
|
+
Do select-menu pobrać tę listę z tej tabelki.
|
34
|
+
|
35
|
+
Dodać „full text search”. Wykorzystać gem
|
36
|
+
[xapit](http://github.com/ryanb/xapit/) albo
|
37
|
+
[thinking-sphinx](http://github.com/freelancing-god/thinking-sphinx/).
|
38
|
+
Przykład korzystający *thinking-sphinx* można obejrzeć
|
39
|
+
na screencaście R. Batesa,
|
40
|
+
[Thinking Sphinx](http://railscasts.com/episodes/120-thinking-sphinx).
|
41
|
+
|
42
|
+
Użyć innego ORM, np. Datamapper
|
43
|
+
\([przykład](http://github.com/dkubb/datamapper-on-rails/)\).
|
44
|
+
|
45
|
+
|
46
|
+
3\. [A code snippet tool, intended for localhost usage](http://github.com/navyrain/navysnip/)
|
47
|
+
|
48
|
+
Add the following:
|
49
|
+
|
50
|
+
* Command line submission script
|
51
|
+
* Doubleclick to select all
|
52
|
+
* Submit-to-pastie button
|
53
|
+
* Search
|
54
|
+
* Add Rails-ish parsers to SHJS (erb, haml, sass)
|
55
|
+
* Tweak the PRE CSS or do something clever with wrapping
|
56
|
+
to make long lines display nicely
|
57
|
+
|
58
|
+
|
59
|
+
4\. [Extremely Simple Photo Album in
|
60
|
+
Rails](http://rubyplus.org/episodes/92-Extremely-Simple-Photo-Album-in-Rails.html)
|
61
|
+
|
62
|
+
* You can extend this album so that the photo upload does not tie up
|
63
|
+
the Mongrel process by using Background DRB, Merb etc.
|
64
|
+
* Add the feature where users can only add/edit photos to their album.
|
65
|
+
* When a photo is added instead of displaying the album index page,
|
66
|
+
display the album show page so that users can continue uploading
|
67
|
+
photos.
|
@@ -0,0 +1,592 @@
|
|
1
|
+
#### {% title "Fortunka" %}
|
2
|
+
|
3
|
+
# Fortunka w Ruby on Rails
|
4
|
+
|
5
|
+
Zaczynamy od wygenerowania szkieletu aplikacji:
|
6
|
+
|
7
|
+
rails fortune
|
8
|
+
|
9
|
+
Generator rails utworzył wiele katalogów. Po co?
|
10
|
+
|
11
|
+
cd fortune
|
12
|
+
|
13
|
+
I juz mozemy przetestować szkielet aplikacji.
|
14
|
+
Uruchamiamy cienkiego:
|
15
|
+
|
16
|
+
script/server thin -p 3000
|
17
|
+
|
18
|
+
i oglądamy stronę testową:
|
19
|
+
|
20
|
+
http://localhost:3000
|
21
|
+
|
22
|
+
Plikowi ze stroną, którą oglądamy zmieniamy nazwę
|
23
|
+
na `welcome.html`:
|
24
|
+
|
25
|
+
cd public
|
26
|
+
mv index.html welcome.html
|
27
|
+
|
28
|
+
Teraz strona ta dosŧepna jest pod takim url:
|
29
|
+
|
30
|
+
http://localhost:3000/welcome.html
|
31
|
+
|
32
|
+
A stronę główną aplikacji wykonamy za chwilę.
|
33
|
+
|
34
|
+
|
35
|
+
## Generujemy rusztowanie dla modelu Education
|
36
|
+
|
37
|
+
Zaczynamy od nauczenia Rails, że liczba mnoga od
|
38
|
+
*education* to *education*.
|
39
|
+
|
40
|
+
**Oj będą problemy!**
|
41
|
+
|
42
|
+
W pliku *inflections.rb* dopisujemy regułę:
|
43
|
+
|
44
|
+
:::ruby
|
45
|
+
# Add new inflection rules using the following format
|
46
|
+
# (all these examples are active by default):
|
47
|
+
ActiveSupport::Inflector.inflections do |inflect|
|
48
|
+
# inflect.plural /^(ox)$/i, '\1en'
|
49
|
+
# inflect.singular /^(ox)en/i, '\1'
|
50
|
+
# inflect.irregular 'person', 'people'
|
51
|
+
# inflect.uncountable %w( fish sheep )
|
52
|
+
inflect.uncountable %w( education )
|
53
|
+
end
|
54
|
+
|
55
|
+
Teraz podejrzymy jakie generatory są zainstalowane w systemie:
|
56
|
+
|
57
|
+
./script/generate
|
58
|
+
|
59
|
+
Installed Generators
|
60
|
+
... scaffold ...
|
61
|
+
|
62
|
+
./script/generate scaffold
|
63
|
+
|
64
|
+
Description:
|
65
|
+
Scaffolds an entire resource, from model and migration to controller and
|
66
|
+
views, along with a full test suite. The resource is ready to use as a
|
67
|
+
starting point for your RESTful, resource-oriented application.
|
68
|
+
|
69
|
+
Model *Education* wygenerujemy tak:
|
70
|
+
|
71
|
+
./script/generate scaffold Education author:string quotation:text
|
72
|
+
|
73
|
+
Polecenie:
|
74
|
+
|
75
|
+
./script/generate scaffold Computer ..
|
76
|
+
|
77
|
+
utworzy następujące pliki:
|
78
|
+
|
79
|
+
<table class="span-19" summary="Scaffold">
|
80
|
+
<colgroup>
|
81
|
+
<col class="table1"/>
|
82
|
+
<col class="table2"/>
|
83
|
+
</colgroup>
|
84
|
+
<caption><em>Domyślne rusztowanie</em></caption>
|
85
|
+
<thead>
|
86
|
+
<tr>
|
87
|
+
<th class="span-8">Plik</th>
|
88
|
+
<th class="span-11">Po co?</th>
|
89
|
+
</tr>
|
90
|
+
</thead>
|
91
|
+
|
92
|
+
<tbody>
|
93
|
+
<tr>
|
94
|
+
<td>app/models/post.rb</td>
|
95
|
+
<td>The Computer model</td>
|
96
|
+
</tr>
|
97
|
+
|
98
|
+
<tr>
|
99
|
+
<td>db/migrate/......._create_computers.rb</td>
|
100
|
+
<td>Migration to create the computers table in your database</td>
|
101
|
+
</tr>
|
102
|
+
|
103
|
+
<tr>
|
104
|
+
<td>app/controllers/computers_controller.rb</td>
|
105
|
+
<td>The Computers controller</td>
|
106
|
+
</tr>
|
107
|
+
|
108
|
+
<tr>
|
109
|
+
<td>app/views/computers/index.html.erb</td>
|
110
|
+
<td>A view to display an index of all computers</td>
|
111
|
+
</tr>
|
112
|
+
|
113
|
+
<tr>
|
114
|
+
<td>app/views/computers/show.html.erb</td>
|
115
|
+
<td>A view to display a single post</td>
|
116
|
+
</tr>
|
117
|
+
|
118
|
+
<tr>
|
119
|
+
<td>app/views/computers/new.html.erb</td>
|
120
|
+
<td>A view to create a new post</td>
|
121
|
+
</tr>
|
122
|
+
|
123
|
+
<tr>
|
124
|
+
<td>app/views/computers/edit.html.erb</td>
|
125
|
+
<td>A view to edit an existing post</td>
|
126
|
+
</tr>
|
127
|
+
|
128
|
+
<tr>
|
129
|
+
<td>app/views/layouts/computers.html.erb</td>
|
130
|
+
<td>A view to control the overall look and feel of the other computers views</td>
|
131
|
+
</tr>
|
132
|
+
|
133
|
+
<tr>
|
134
|
+
<td>public/stylesheets/scaffold.css</td>
|
135
|
+
<td>Cascading style sheet to make the scaffolded views look better</td>
|
136
|
+
</tr>
|
137
|
+
|
138
|
+
<tr>
|
139
|
+
<td>app/helpers/computers_helper.rb</td>
|
140
|
+
<td>Helper functions to be used from the computers views</td>
|
141
|
+
</tr>
|
142
|
+
|
143
|
+
<tr>
|
144
|
+
<td>config/routes.rb</td>
|
145
|
+
<td>Edited to include routing information for computers</td>
|
146
|
+
</tr>
|
147
|
+
|
148
|
+
<!--
|
149
|
+
|
150
|
+
<tr>
|
151
|
+
<td>test/functional/computers_controller_test.rb</td>
|
152
|
+
<td>Functional testing harness for the computers controller</td>
|
153
|
+
</tr>
|
154
|
+
|
155
|
+
<tr>
|
156
|
+
<td>test/fixtures/computers.yml</td>
|
157
|
+
<td>Dummy computers for use in testing</td>
|
158
|
+
</tr>
|
159
|
+
|
160
|
+
<tr>
|
161
|
+
<td>test/unit/post_test.rb</td>
|
162
|
+
<td>Unit testing harness for the computers model</td>
|
163
|
+
</tr>
|
164
|
+
|
165
|
+
<tr>
|
166
|
+
<td>test/unit/helpers/computers_helper_test.rb </td>
|
167
|
+
<td>Unit testing harness for the computers helper</td>
|
168
|
+
</tr>
|
169
|
+
|
170
|
+
-->
|
171
|
+
|
172
|
+
</tbody>
|
173
|
+
</table>
|
174
|
+
|
175
|
+
|
176
|
+
Migrujemy:
|
177
|
+
|
178
|
+
rake db:create
|
179
|
+
rake db:migrate
|
180
|
+
|
181
|
+
Podglądamy routing:
|
182
|
+
|
183
|
+
rake routes
|
184
|
+
|
185
|
+
Stronę z listą cytatów podmontowujemy jako stronę główną witrynki.
|
186
|
+
W tym celu w pliku *routes.rb* edytujemy wiersz z `map.root`:
|
187
|
+
|
188
|
+
:::ruby
|
189
|
+
# You can have the root of your site routed with map.root --
|
190
|
+
# just remember to delete public/index.html.
|
191
|
+
map.root :controller => "education"
|
192
|
+
|
193
|
+
Wyniki naszej pracy możemy podejrzeć tutaj:
|
194
|
+
|
195
|
+
http://localhost:3000
|
196
|
+
|
197
|
+
Ale po kliknięciu na 'NEW' dostajemy *weird error*.
|
198
|
+
Generator wygenerował błędny kod? Poprawiamy generator
|
199
|
+
zamieniając w widokach, `education_path` na `education_index_path`,
|
200
|
+
przykład:
|
201
|
+
|
202
|
+
:::ruby
|
203
|
+
link_to 'Back', education_index_path
|
204
|
+
|
205
|
+
I jeszcze raz podglądamy routing:
|
206
|
+
|
207
|
+
rake routes
|
208
|
+
|
209
|
+
Jeśli nie zmienialibyśmy liczby mnogiej, to w wygenerowanych
|
210
|
+
widokach byłoby tak:
|
211
|
+
|
212
|
+
:::ruby
|
213
|
+
link_to 'Back', educations
|
214
|
+
|
215
|
+
i nie byłoby problemów, a tak mamy wygenerowany
|
216
|
+
link z `education` i rails oczekuje jakiegoś `id`
|
217
|
+
(dlaczego?, konwencja REST).
|
218
|
+
|
219
|
+
|
220
|
+
## A co z polskimi literkami?
|
221
|
+
|
222
|
+
Komunikaty o błędach też powinny być po polsku.
|
223
|
+
Jak to zrobić? Zaglądamy do katalogu *locales* po
|
224
|
+
wskazówki:
|
225
|
+
|
226
|
+
:::ruby
|
227
|
+
# Sample localization file for English.
|
228
|
+
# Add more files in this directory for other locales.
|
229
|
+
# See http://github.com/svenfuchs/rails-i18n/tree/master/rails%2Flocale
|
230
|
+
# for starting points.
|
231
|
+
|
232
|
+
Obejrzenie, krótkiego
|
233
|
+
[screecastu R. Batesa](http://railscasts.com/episodes/138-i18n)
|
234
|
+
też ma sens.
|
235
|
+
|
236
|
+
W pliku *environment.rb* odkomentowujemy i edytujemy wiersz
|
237
|
+
z `config.i18n.default_locale`:
|
238
|
+
|
239
|
+
# The default locale is :en and all translations
|
240
|
+
# from config/locales/*.rb,yml are auto loaded.
|
241
|
+
# config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}')]
|
242
|
+
config.i18n.default_locale = :pl
|
243
|
+
end
|
244
|
+
|
245
|
+
## Suszymy kod: refaktoryzacja widoków
|
246
|
+
|
247
|
+
Wspólny kod z plików *new.html.erb* oraz *edit.html.erb*
|
248
|
+
przenosimy do pliku *_form.htm.erb*. Zamiast tego kodu
|
249
|
+
wstawiamy w pliku *new.html.erb*:
|
250
|
+
|
251
|
+
:::html_rails
|
252
|
+
<%= render :partial => "form",
|
253
|
+
:locals => { :f => f, :button_label => 'Create' } %>
|
254
|
+
|
255
|
+
a w pliku *edit.html.erb*:
|
256
|
+
|
257
|
+
:::html_rails
|
258
|
+
<%= render :partial => "form",
|
259
|
+
:locals => { :f => f, :button_label => 'Update' } %>
|
260
|
+
|
261
|
+
|
262
|
+
## Suszymy kod: refaktoryzacja kontrolera za pomocą filtrów
|
263
|
+
|
264
|
+
Jeden wiersz powatarza się cztery razy w różnych akcjach:
|
265
|
+
|
266
|
+
:::ruby
|
267
|
+
class EducationController < ApplicationController
|
268
|
+
...
|
269
|
+
def show
|
270
|
+
@education = Education.find(params[:id])
|
271
|
+
...
|
272
|
+
def edit
|
273
|
+
@education = Education.find(params[:id])
|
274
|
+
...
|
275
|
+
def update
|
276
|
+
@education = Education.find(params[:id])
|
277
|
+
...
|
278
|
+
def destroy
|
279
|
+
@education = Education.find(params[:id])
|
280
|
+
...
|
281
|
+
|
282
|
+
Usuwamy powtarzający się wiersz z akcji/metod i modyfikujemy
|
283
|
+
kod kontrolera w następujący sposób:
|
284
|
+
|
285
|
+
:::ruby
|
286
|
+
class EducationController < ApplicationController
|
287
|
+
before_filter :find_education, :only => [:show, :edit, :update, :destroy]
|
288
|
+
...
|
289
|
+
private
|
290
|
+
def find_education
|
291
|
+
@education = Education.find(params[:id])
|
292
|
+
end
|
293
|
+
end
|
294
|
+
|
295
|
+
## Dodajemy nową kolumnę do tabelki: *source*
|
296
|
+
|
297
|
+
Zaczynamy od rozpoznania terenu:
|
298
|
+
|
299
|
+
script/generate migration
|
300
|
+
|
301
|
+
Po lekturze decydujemy się na taką nazwę migracji:
|
302
|
+
|
303
|
+
script/generate migration AddSourceToEducation source:string
|
304
|
+
|
305
|
+
Wygenerowanego pliku, nie musimy poprawiać:
|
306
|
+
|
307
|
+
:::ruby
|
308
|
+
class AddSourceToEducation < ActiveRecord::Migration
|
309
|
+
def self.up
|
310
|
+
add_column :education, :source, :string
|
311
|
+
end
|
312
|
+
|
313
|
+
def self.down
|
314
|
+
remove_column :education, :source
|
315
|
+
end
|
316
|
+
end
|
317
|
+
|
318
|
+
Migrujemy:
|
319
|
+
|
320
|
+
rake db:migrate
|
321
|
+
|
322
|
+
Teraz poprawiamy wygenerowane widoki, dodając nową kolumnę.
|
323
|
+
|
324
|
+
Uruchamiamy aplikację i edytujemy wpis:
|
325
|
+
|
326
|
+
Oscar Wilde, "The Critic as Artist"
|
327
|
+
|
328
|
+
przerzucając nazwę książki do kolumny *Source*.
|
329
|
+
|
330
|
+
|
331
|
+
## Generujemy rusztowanie dla modelu Frazes (Komunał)
|
332
|
+
|
333
|
+
Teraz uwzględniamy nową kolumnę.
|
334
|
+
|
335
|
+
./script/generate scaffold Platitude author:string source:string quotation:text
|
336
|
+
|
337
|
+
Sprawdzamy jak to działa wpisując kilka komunałów.
|
338
|
+
|
339
|
+
Wykonujemy jeszcze raz te same kroki co przy modelu *Education*.
|
340
|
+
Teraz do partial mozemy wrzucić więcej kodu:
|
341
|
+
nie ma problemu z liczbą pojedynczą i mnogą.
|
342
|
+
|
343
|
+
|
344
|
+
## Problemy, problemy: znowu czeka nas suszenie kodu
|
345
|
+
|
346
|
+
> Given sufficient time, what you put off doing
|
347
|
+
> today will get done by itself.
|
348
|
+
|
349
|
+
Powinniśmy mieć jeden model: *Quotation* z dodatkowym
|
350
|
+
atrybutem *category*. Co robić?
|
351
|
+
|
352
|
+
Na razie skorzystamy z takiego frazesu:
|
353
|
+
|
354
|
+
## Dodajemy Basic HTTP Authentication
|
355
|
+
|
356
|
+
W tabelce *educations* jest trochę fajnych cytatów.
|
357
|
+
Nie chcemy aby ktoś nam grzebał w tabelkach.
|
358
|
+
|
359
|
+
:::ruby
|
360
|
+
class EducationController < ApplicationController
|
361
|
+
# USERNAME, PASSWORD = "wbzyl", "sekret"
|
362
|
+
# logger.info("Digest::SHA1: #{Digest::SHA1.hexdigest('sekret')}")
|
363
|
+
USERNAME, PASSWORD = "wbzyl", "a1b9892611956aa13a5ab9ccf01f49662583f2d2"
|
364
|
+
before_filter :authenticate, :only => [:new, :edit, :destroy]
|
365
|
+
...
|
366
|
+
private
|
367
|
+
def authenticate
|
368
|
+
authenticate_or_request_with_http_basic do |username, password|
|
369
|
+
#username == USERNAME && password == PASSWORD
|
370
|
+
username == USERNAME && (Digest::SHA1.hexdigest(password) == PASSWORD)
|
371
|
+
end
|
372
|
+
end
|
373
|
+
|
374
|
+
Klasyka z railscasts [HTTP Basic
|
375
|
+
Authentication](http://railscasts.com/episodes/82-http-basic-authentication/).
|
376
|
+
|
377
|
+
|
378
|
+
## Digest HTTP Authentication
|
379
|
+
|
380
|
+
> For those that may now know the difference, basic authentication only
|
381
|
+
> base 64 encodes the authenticating username and password (making it
|
382
|
+
> easily decoded) whereas digest authentication sends an MD5 hash of
|
383
|
+
> your username and password. To simplify, digest is more secure than
|
384
|
+
> basic.
|
385
|
+
|
386
|
+
W tabelce * platitudes* też jest trochę fajnych cytatów.
|
387
|
+
Dla odmiany zabezpieczymy cały kontroler za pomocą digest authentication.
|
388
|
+
|
389
|
+
:::ruby
|
390
|
+
class PlatitudesController < ApplicationController
|
391
|
+
USERS = { "wbzyl" => "sekret" }
|
392
|
+
before_filter :authenticate
|
393
|
+
...
|
394
|
+
def authenticate
|
395
|
+
authenticate_or_request_with_http_digest do |username|
|
396
|
+
USERS[username]
|
397
|
+
end
|
398
|
+
end
|
399
|
+
end
|
400
|
+
|
401
|
+
## Paginacja
|
402
|
+
|
403
|
+
Skorzystamy z gemu
|
404
|
+
[will_paginate](http://github.com/mislav/will_paginate/)
|
405
|
+
|
406
|
+
W pliku *environment.rb* dopisujemy:
|
407
|
+
|
408
|
+
:::ruby
|
409
|
+
Rails::Initializer.run do |config|
|
410
|
+
config.gem 'mislav-will_paginate', :version => '~> 2.3.6', :lib => 'will_paginate',
|
411
|
+
:source => 'http://gems.github.com'
|
412
|
+
end
|
413
|
+
|
414
|
+
i po kończącym blok end dopisujemy:
|
415
|
+
|
416
|
+
:::ruby
|
417
|
+
end
|
418
|
+
require "will_paginate"
|
419
|
+
|
420
|
+
Następnie sprawdzamy czy gem jest już zainstalowany w odpowiedniej wersji:
|
421
|
+
|
422
|
+
rake gems
|
423
|
+
|
424
|
+
Jeśli nie to wykonujemy polecenie:
|
425
|
+
|
426
|
+
rake gems:install
|
427
|
+
|
428
|
+
Tyle o instalacji.
|
429
|
+
|
430
|
+
W kodzie metody `index` kontrolera *Education* wymieniamy wiersz:
|
431
|
+
|
432
|
+
:::ruby
|
433
|
+
@education = Education.all
|
434
|
+
|
435
|
+
na
|
436
|
+
|
437
|
+
:::ruby
|
438
|
+
@education = Education.paginate :page => params[:page], :per_page => 5,
|
439
|
+
:order => 'updated_at DESC'
|
440
|
+
|
441
|
+
W widoku *index* dopisujemy:
|
442
|
+
|
443
|
+
:::html_rails
|
444
|
+
<%= will_paginate @education %>
|
445
|
+
|
446
|
+
No jeszcze należy wystylizować element:
|
447
|
+
|
448
|
+
:::html
|
449
|
+
<div class="pagination">
|
450
|
+
|
451
|
+
Tworzymy plik *application.css* gdzie wpisujemy:
|
452
|
+
|
453
|
+
:::css
|
454
|
+
.pagination {
|
455
|
+
margin-top: 1em;
|
456
|
+
}
|
457
|
+
|
458
|
+
Nowy plik stylu dopisujemy w layoucie kontrolera.
|
459
|
+
|
460
|
+
|
461
|
+
## Dodajemy obrazki korzystając z gemu Paperclip
|
462
|
+
|
463
|
+
Do każdego cytatu będzie można dodać obrazek ze zdjęciem
|
464
|
+
autora cytatu lub czegokolwiek.
|
465
|
+
|
466
|
+
Tutaj znalazłem krótke howto:
|
467
|
+
[The Ruby On Rails Paperclip Plugin Tutorial - Easy Image
|
468
|
+
Attachments](http://burm.net/2008/10/07/the-ruby-on-rails-paperclip-plugin-tutorial-easy-image-attachments/)
|
469
|
+
|
470
|
+
Jak zwykle sprawdzamy czy gem jest już zainstalowany:
|
471
|
+
|
472
|
+
gem list
|
473
|
+
|
474
|
+
Jeśli nie to instalujemy go tak:
|
475
|
+
|
476
|
+
gem sources -a http://gems.github.com
|
477
|
+
sudo gem install thoughtbot-paperclip
|
478
|
+
|
479
|
+
albo, lepiej, w pliku *environment.rb* dopisujemy:
|
480
|
+
|
481
|
+
:::ruby
|
482
|
+
Rails::Initializer.run do |config|
|
483
|
+
config.gem 'thoughtbot-paperclip', :version => '~> 2.2.8', :lib => 'paperclip',
|
484
|
+
:source => 'http://gems.github.com'
|
485
|
+
end
|
486
|
+
|
487
|
+
i teraz wykonujemy
|
488
|
+
|
489
|
+
sudo rake gems:install
|
490
|
+
|
491
|
+
OK. Chcemy mieć attaczmęt w modelu *Education*. Nazwiemy go *photo*.
|
492
|
+
|
493
|
+
Generujemy migrację:
|
494
|
+
|
495
|
+
script/generate migration AddPhotosToEducation \
|
496
|
+
photo_file_name:string photo_content_type:string photo_file_size:integer
|
497
|
+
|
498
|
+
Migrujemy:
|
499
|
+
|
500
|
+
rake db:migrate
|
501
|
+
|
502
|
+
W modelu *Education* wpisujemy:
|
503
|
+
|
504
|
+
:::ruby
|
505
|
+
# paperclip
|
506
|
+
has_attached_file :photo, :styles => {
|
507
|
+
:thumb=> "100x100#",
|
508
|
+
:small => "150x150>",
|
509
|
+
}
|
510
|
+
|
511
|
+
W formularzach umieszczonych w widokach dopisujemy:
|
512
|
+
`html => { :multipart => true }`:
|
513
|
+
|
514
|
+
:::html_rails
|
515
|
+
# edit.html.erb
|
516
|
+
<% form_for(@education, :html => { :multipart => true }) do |f| %>
|
517
|
+
# new.html.erb
|
518
|
+
<% form_for(@education, :url => education_index_path,
|
519
|
+
:html => { :multipart => true }) do |f| %>
|
520
|
+
|
521
|
+
W widoku częściowym (partial) *_form.html.erb* dopisujemy:
|
522
|
+
|
523
|
+
:::html_rails
|
524
|
+
<p>
|
525
|
+
<%= f.label 'Photo' %><br />
|
526
|
+
<%= f.file_field :photo %>
|
527
|
+
</p>
|
528
|
+
|
529
|
+
W widoku *index.html.erb* dopisujemy:
|
530
|
+
|
531
|
+
:::html_rails
|
532
|
+
<% if education.photo.exists? %>
|
533
|
+
<td><%= image_tag education.photo.url(:thumb) %></td>
|
534
|
+
<% else %>
|
535
|
+
<td>[no photo]</td>
|
536
|
+
<% end %>
|
537
|
+
|
538
|
+
W widoku *show.html.erb* dopisujemy:
|
539
|
+
|
540
|
+
:::html_rails
|
541
|
+
<% if @education.photo.exists? %>
|
542
|
+
<p><%= image_tag @education.photo.url(:small) %></p>
|
543
|
+
<% else %>
|
544
|
+
<p> There are no photo's attached, upload one.</p>
|
545
|
+
<% end %>
|
546
|
+
|
547
|
+
|
548
|
+
## Dodajemy middleware: Rack::HtmlTidy
|
549
|
+
|
550
|
+
Jak walidować HTML stron wygenerowanych przez Rails?
|
551
|
+
Wchodzenie na stronę [W3C Markup Validation Service](http://validator.w3.org/)
|
552
|
+
i ręczne wklejanie adresów jest uciążliwe i męczące.
|
553
|
+
Może zainstalować jakiś dodatek do Firefoxa? Może…
|
554
|
+
|
555
|
+
A może tak „prześwietlić” wygenerowaną stronę
|
556
|
+
HTML Tidy? Jak to zrobić opisałem na
|
557
|
+
[github.com](http://github.com/wbzyl/rack-htmltidy/).
|
558
|
+
|
559
|
+
|
560
|
+
## Tytuły stron (bardzo ważne)
|
561
|
+
|
562
|
+
W pliku z metodami pomocniczymi dla całej aplikacji wpisujemy:
|
563
|
+
|
564
|
+
:::ruby
|
565
|
+
module ApplicationHelper
|
566
|
+
def title(title)
|
567
|
+
content_for(:title) { title }
|
568
|
+
end
|
569
|
+
end
|
570
|
+
|
571
|
+
W layoutach podmieniamy wygenerowany tytuł
|
572
|
+
|
573
|
+
:::html_rails
|
574
|
+
<title>Education: <%= controller.action_name %></title>
|
575
|
+
|
576
|
+
na
|
577
|
+
|
578
|
+
:::html_rails
|
579
|
+
<title><%= yield(:title) || "WB_Quotations" -%></title>
|
580
|
+
|
581
|
+
W widokach definiujemy tytuł wpisując:
|
582
|
+
|
583
|
+
:::html_rails
|
584
|
+
<% title 'WB_RAILS – Aktywne bazy danych' -%>
|
585
|
+
|
586
|
+
|
587
|
+
## Różne
|
588
|
+
|
589
|
+
Skorzystać z wtyczki:
|
590
|
+
Bryan Helmkamp,
|
591
|
+
[rack-bug](http://github.com/brynary/rack-bug/) —
|
592
|
+
debugging toolbar for Rack applications implemented as middleware.
|