Nusprendžiau pailsėti nuo C# ir grįžti prie internetinių aplikacijų kūrimo. Norėčiau pradžiuginti visus Ruby on Rail gerbėjus, kurie jau pradėjo pasigesti straipsnių šia tema pixel.lt tinklapyje. Tai štai pagaliau parašiau savo pirmąją programą ant bėgių.
Paprastai daugelis mėgsta pirmąją savo programą pavadinti „Labas pasauli“, aš irgi norėjau sukurti kažką labai paprasto bet truputį prasmingesnio. Pažiūrėkim kas gavosi.

Užduotis. Sukurti užrašų knygutę, kurios užrašus galėtų peržiūrėti bet kas, tačiau rašyti naujus, redaguoti, savaime suprantama tik aš.
Pradedam darbus:

rails notebook

Šita eilutė sugeneravo mūsų programos šabloną. Dabar atsidarome katalogą ir tolesni darbai vyks jame

cd notebook

Kaip jau supratote iš užduoties, programai reikės prisijungimo, todėl ir įsidėkime jį iš karto. Jeigu neturite jums pirmiausiai reikės įsidiegti login_generator bibliotekas

gem install login_generator

O jeigu turite tiesiog susigeneruokite prisijungimą

ruby script/generate login User

Kandangi jau turime prisijungimo skriptą dabar pats laikas susikurti duomenų lentelę. (Pastaba: aš šį kartą neaiškinsiu kaip susikonfigūruoti duomenų bazės failą database.yml, jeigu bus pageidaujančių parašysiu atskirai). Pagal prisijungimo skriptą mums reikia susikurti tokią lentelę:

CREATE TABLE users (
id int(11) NOT NULL AUTO_INCREMENT,
login varchar(80) DEFAULT NULL,
password varchar(40) DEFAULT NULL,
PRIMARY KEY  (id)
);

Šiuo atveju tokia lentelė mus pilnai tenkina. Čia turbūt reiktų paaiškinti, jog pagal susitarimą visų lentelių pirmas laukas privalo būti sveikųjų tipo ir vadintis id.
Jeigu viską sugebėjote pasidaryti iki šios vietos, tai galima startuoti serverį

ruby script\server

ir pasižiūrėti ką turime: http://localhost:3000/. Taip šitą vaizdelį reikės pakeisti vėliau. O dabar pabandykite kitą adresą: http://localhost:3000/user/login Hm, vartotojo mes dar neturim, todėl pirmiausia jį reiktų susikurti: http://localhost:3000/user/signup . Aš šiuo atveju susikursiu admin/admin, jūs aišku, galėtumėte susikurti kažką prasmingesnio. Hm, gavau labai negražų pranešimą, nes prieš kurdamas vartotoją pamiršau paredaguoti app\controllers\application.rb failą. Atsidarę tą failą randame tokį kodą:

class ApplicationController < ActionController::Base
end

Kitaip, sakant tuščia, tad jį patobuliname:

require_dependency "login_system"
class ApplicationController < ActionController::Base
include LoginSystem
model :user
end

Dabar tiek registracija, tiek prisijungimas veikia be problemų.

Pagalvokim kaip turėtų atrodyti užrašų knygutė: manyčiau reiktų pavadinimo, teksto, sukūrimo datos. Užteks, o gal yra dar pasiūlymų? Mano lentelės kodas atrodo sekančiai:

CREATE TABLE `notes` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`title` varchar(100) NOT NULL DEFAULT '',
`story` text NOT NULL,
`created_at` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
PRIMARY KEY  (`id`)
);

Norėčiau visų jūsų dėmesį atkreipti į lauką created_at susitarimu datetime tipo laukų pavadinimai turėtų baigtis _at, o date - _on. Tai dar vienas cirkas susijęs su geresniu skambėjimu anglų kalboje.
Čia aš leisiu sau pasielgti nekorektiškai ir iškarto sugeneruosiu sekantį kodą:

ruby script/generate scaffold note

Daug korektiškiau būtų buvę pirmiau susikurti model ir controler. Šis kodas sugeneravo visą duomenų lentelės notes valdymą. Turbūt atkreipėte dėmesį, jog modelio pavadinimas vienaskaita, o visos lentelės - daugiskaita, ką gi tai dar viena taisyklė. Jeigu norime pamatyti, ką padarėm, reiktų nueiti http://localhost:3000/notes/list adresu (nepamirškite startuoti serverio). Aišku mes ten nieko įspūdingo nepamatysime tik siūlymą sukurti naują įrašą. Taip ir padarykime, aš sukūriau netgi du.
Koks stebuklas, dar neparašėme nei vienos kodo eilutės, o tokius dalykus galime daryti! Jeigu jūs norit galite dar pasidžiaugti šiu stebuklu, o aš parašysiu porą kodo eilučių.

Pirmiausia turbūt reikia užtikrinti, kad nebūtų įvesti užrašai be pavadinimo ar turinio, tam reikia paredaguoti app\models\note.rb failą:

class Note < ActiveRecord::Base
validates_presence_of :title, :story
end

Pabandykite dabar įterpti naują įrašą be pavadinimo arba turinio. Nepavyko?
Važiuojam toliau. Mes norėtume, kad prisijungus mums parodytų ne kokį nors “welcome” langą, bet būtent visus įrašus, tam turėsime paredaguoti app\controlers\user_controller.rb failą. Konkrečiau:

redirect_back_or_default :action => "welcome"

šį kodą pakeisim sekančiu:

redirect_back_or_default :controller => 'notes', :action => 'index'

Pabandykit. Veikia? Tiesa, mes dar nieko nedarėme, kad apsaugotume įrašus ir todėl juos gali redaguoti kas nori, tuoj pat pataisykime tai atsidarę failą app\controlers\notes_controller.rb

before_filter :login_required, :except => [:index, :list, :show]

Šią eilutę įterpiame iš karto po klasės aprašo. Kaip matote padarėme tris išimtis, čia tam kad patenkintume užduoties sąlygą, jog įrašus gali matyt kiekvienas ir tam nereikia prisijungimo. Jeigu dabar pabandytumėte paredaguoti jums, be abejonės, nepavyktų (pastaba: nepamirškite atsijungti).
Tas vaizdas, kurį mes matome, aiškiai netenkina mūsų (bent jau manęs), todėl mes jį pakeisime. Pirmiausiai paredaguosime app\views\notes\list.rhtml. Ten esantį kodą pakeičiam į sekantį:

<h1>My notes</h1>
<table>
<% for note in @notes %>
  <tr>
  <td colspan="4"><%= h(note.title) %><br />
  <%= note.created_at.strftime("%Y-%m-%d %H:%M") %><br />
  <%= h(truncate(note.story, 80)) %>
  </td>
  </tr>
	<tr>
     <td><%= link_to 'Show', :action => 'show', :id => note %></td>
     <td><%= link_to 'Edit', :action => 'edit', :id => note %></td>
    <td><%= link_to 'Destroy', { :action => 'destroy', :id => note }, :confirm => 'Are you sure?', :post => true %></td>
  <td><%= link_to 'New', :action => 'new' %></td>
    </tr>
<% end %>
</table>
 <%= link_to 'Previous page', { :page => @note_pages.current.previous } if @note_pages.current.previous %>
<%= link_to 'Next page', { :page => @note_pages.current.next } if @note_pages.current.next %>

Turbūt reiktų paaiškinti ką padariau? Pirmiausia cikle iš lentelės notes pasiėmiau įrašą. Funkcija h() pašalina žalingus html tagus. (O čia akmuo į Ruby kūrėjų daržą, koks idiotas sugalvojo sukurti funkciją, kurios pavadinimas iš vienos raidės? Pabandykit dabar dokumentacijos surasti apie tą funkciją). Sekančioje eilutėje duomenų bazėje saugomą laiko formatą pakeičiu į žmogui labiau suprantamą. Funkcija truncate() nukerpa tekstą, šiuo atveju, iki 80 simbolių. Aš taip pat nuorodą naujo įrašo sukūrimui perkėliau prie kitų.
Dabar reiktų paredaguoti app\views\notes\show.rhtml failą. Ten esantį kodą pakeičiu:

<%= h(@note.title) %>
<%= @note.created_at.strftime("%Y-%m-%d %H:%M") %>
<%= h(@note.story) %>
 
<%= link_to 'Edit', :action => 'edit', :id => @note %> |
<%= link_to 'Back', :action => 'list' %>

@note vienas įrašas paimtas iš duomenų bazės, pagal vartotojo nurodytą id.
Pats laikas pasidaryti pagrindinį programos failą. Šiuo atveju app\views\notes direktorijoje susikursiu index.rhtml su tokiu turiniu:

<html>
 <head>
 <title>My First Ruby App</title>
 </head>
 <body>
 <table>
 <tr><td>
<%= render_component(:controller => "notes", :action => "list") %>
</td><td>
<%= render_component(:controller => "user", :action => "login") %>
</td></tr>
 </body>
 </html>

Tada reikia atsidaryti config\routes.rb failą ir įterpti vieną įrašą:

map.connect '', :controller => 'note', :action => 'index'

Nepamirškite ištrinti failo public\index.html Dabar nueikite adresu http://localhost:3000/ šaunu? Nelabai - paprastas vartotojas neturi teises nei kurti naujų įrašų, nei jų redaguoti, tai reiktų paslėpti. Dar kartą atsidarykim iš pradžių app\views\notes\list.rhtml ir patobulinkime kodą:

<h1>My notes</h1>
<table>
<% for note in @notes %>
  <tr>
  <td colspan="4"><%= h(note.title) %><br />
  <%= note.created_at.strftime("%Y-%m-%d %H:%M") %><br />
  <%= h(truncate(note.story, 80)) %>
  </td>
  </tr>
<tr>
     <td><%= link_to 'Show', :action => 'show', :id => note %></td>
      <% if !@session['user'].nil? %>
    <td><%= link_to 'Edit', :action => 'edit', :id => note %></td>
    <td><%= link_to 'Destroy', { :action => 'destroy', :id => note }, :confirm => 'Are you sure?', :post => true %></td>
  <td><%= link_to 'New', :action => 'new' %></td>
  <% end %>
    </tr>
<% end %>
</table>
 <% if !@session['user'].nil? %>
 <%= link_to "&#171; logout", :controller => user, :action=>"logout"%>
 <% end %>
<%= link_to 'Previous page', { :page => @note_pages.current.previous } if @note_pages.current.previous %>
<%= link_to 'Next page', { :page => @note_pages.current.next } if @note_pages.current.next %>

Ką aš padariau? Įdėjau paprastą patikrinimą if !@session[’user’].nil? , jeigu vartotojas neprisijungęs, jis nemato kai kurių meniu punktų. Taip pat įdėjau galimybę atsijungti, jeigu vartotojas prisijungęs. Analogiškai reikia patobulinti ir app\views\notes\show.rhtml failą:

<%= h(@note.title) %>
<%= @note.created_at.strftime("%Y-%m-%d %H:%M") %>
<%= h(@note.story) %>
 
<% if !@session['user'].nil? %>
<%= link_to 'Edit', :action => 'edit', :id => @note %> |
<% end %>
<%= link_to 'Back', :action => 'list' %>

Na va, dabar daug geriau. Tik bėda neveikia prisijungimas. Tai atsitiko dėl mūsų cirko su index.rhtml failu, kad išspręstumėm šią bėdą reikia atsidaryti app\views\user\login.rhtml failą ir pataisyti pirmą eilutę:

<%= start_form_tag :controller => “user”, :action=> “login” %>

Ką aš padariau? Nurodžiau kontrolerį, kuris naudojamas atliekant šį veiksmą.
Jau viskas?
Ne. Pabandykite užsikrauti adresą http://localhost:3000/notes/show/123456 gražu? Tokio įrašo nėra, todėl programa lūžta. Daugumos php „meistrų“ problema, kad jie niekada nesirūpina tokiomis apsaugomis, tačiau to mes sau leisti negalim. Atsidarykime failą app\controllers\notes_controller.rb ir patobulinkime dvi funkcijas show bei edit

def show
@note = Note.find(params[:id])
rescue
flash[:notice] = 'No info available'
redirect_to(:action => 'index')
end def edit
@note = Note.find(params[:id])
rescue
flash[:notice] = 'No info available'
redirect_to(:action => 'index')
end

Trečioji eilutė pagauna klaidos pranešimą. Ketvirtajai mes nurodome, kokį pranešimą turėtų matyti vartotojas, o penktosios pagalba pasiunčiame vartotoją į pagrindinį mūsų tinklapį.
Dar liko funkcijos signup ir delete. Juk nenorėtume, kad bet kas prisiregistruotų į mūsų užrašų knygutę. Kaip pasielgti? Jeigu žinotume, jog tų funkcijų mums tikrai nereiks galėtume ištrinti. Antras būdas apriboti priėjimą prie jų ir leisti tik registruotiems vartotojams. Trečias būdas padaryti jas “private”. Rinkitės kurį norit, bet taip kaip yra palikti negalima.
Dabar jau tikrai šiam kartui viskas.Ko aš nepadariau? Visiškai nekreipiau dėmesio į bent kiek estetiškesnį dizainą.

Ką aš padariau ne taip? Jeigu užsikrausite pagrindinį langą tai matysite ir savo parašytus užrašus, ir prisijungimo langą, tačiau, kai paspausite „show“, prisijungimo langas dings, o paspaudus „back“ jis taip ir neatsiras. Būtų galima paredaguoti list.rhtml bei show.rhtml ir įtraukti nuorodą į prisijungimo langą, bet galbūt kas nors galėtų pasiūlyti teisingesnį variantą?

    Klausimai:
    ar reiktų parašyti:

  • kaip susikonfigūruoti database.yml?
  • kaip susikurti migration failą ir kam jis reikalingas?
  • kas yra MVC ir kuo jis svarbus ?

Parsisiuntimui
programa kurią sukurėme
tiesiog susikonfigūruokite database.yml ir rake migrate

Pataisymas:Dėl WordPress kodo įskiepio klaidų dalis kodo buvo dingę arba pateikiamas neteisingai. Atsiprašome.

Panašūs straipsniai


“Mano pirmoji Ruby on Rails programa” komentarų: 9

  1. Rar

    rar rar rar :D

    Tai kodėl visgi ne (g)zip?

  2. ernetas

    Todėl, nes RAR’as populiaresnis tarp Windows vartotojų ir kitų sistemų vartotojam riekia prie to taikstytis :) .

  3. mid

    rar? tarp windows vartotoju? :))))

  4. lukoko

    o kuo ruby gėris? gal kas galit pateikt argumentų kodėl ruby geriau už java ar tą patį php?

  5. jungle

    nes ten viska galima padaryti su juo per 5 min :)

  6. enc

    jungle - nemaišyk Ruby su Ruby on Rails.

  7. Rimantas

    a) Visai gražu būtų naudoti migrations.
    b) _at ir _on ne dėl geresnio skambėjimo, o dėl geresnio atitikimo: “on Friday at 16:00″.
    c) h() dokumentacija: http://ruby-doc.org/stdlib/libdoc/erb/rdoc/classes/ERB/Util.html#M000377

  8. bigzel

    d)Rekomenduojama vietoj @session naudoti session:
    http://weblog.rubyonrails.org/2006/4/25/use-params-not-params

  9. Datos ant bėgių Pixel.lt

    […] Aš jau sukuriau savo pirmąją programą Ruby on Rails. Tie, kas atidžiai skaitė pastebėjo, kad naują note galima įterpti bet kuria data. Galbūt kai kam tai yra gerai, tačiau man prisireikė tokį dalyką uždrausti ir pasirodė, kad apie tai informacijos ne tiek jau ir daug. Taigi mano tikslas uždrausti informacijos įvedimą atbuline data. Pirmiausiai aptarsiu savo sugalvotus būdus kaip tai padaryti: 1) Atsidaryti failą views/notes/_form.rhtml ir vietoj kodo: […]

Rašyti komentarą

Jūs privalote prisijungti jeigu norite rašyti komentarą.