Halusin lisätä tehtävälistaukseen päivän, jolloin tehtävä on saatu valmiiksi.
Tietokantaan tehtävänluontipäivämäärä on tallentunut automaattisesti luotuun created_at -kenttään.
Jos sen sisältämää tietoa käyttää suoraan, saa tämän tapaisen pätkän:
task.created_at -> 2014-10-13 19:31:57 UTC
Tästä "raaka-ajasta" voi poimia ja muotoilla strftime:lla haluamiaan osia tämän ohjeen mukaan
task.created_at.strftime("%d.%m.%y") -> 13.10.14
Nyt näyttää jo aika hyvältä!
perjantai 14. marraskuuta 2014
torstai 30. lokakuuta 2014
Edistyminen haittaa edistymistä
Yritän saada mukaan jonkinlaista mittaria edistymiselle ja tavoitetta kohti etenemiselle. Mittari olkoon numero, ajatellaan sitä vaikka prosenttina. Kun tavoite luodaan, numeron pitäisi alkaa automaattisesti nollasta ja käyttäjä saisi päivittää sitä.
Ensimmäinen haasteeni oli saada tavoitteenluontilomakkeeseen piilokenttä välittämään nolla controllerille. Lisäsin lomakkeeseen seuraavan rivin:
<%= hidden_field_tag 'progress', 0 %>
Näin sain aikaan html-koodin
<input id="progress" name="progress" type="hidden" value="0" />
kuten pitikin. Sitten tulikin tenkkapoo. Lomakkeeni kyllä lähetti hienosti progress-muuttujan, mutta controller ei tallentanut sitä tietokantaan.
Started POST "/projects/5/goals" for 127.0.0.1 at 2014-10-30 12:56:05 +0200
Processing by GoalsController#create as HTML
Parameters: {"utf8"=>"V", "authenticity_token"=>"JFtUcbAFJiAs8y08trBS/y/KqmrlIOsfrkppFAqwabE=", "goal"=>{"title"=>"Tavoite1", "description"=>"Kuvaus1", "celebration"=>"Juhlistus1"}, "progress"=>"0",
"commit"=>"Luo tavoite", "project_id"=>"5"}
DEBUG params inspect {"utf8"=>"V", "authenticity_token"=>"JFtUcbAFJiAs8y08trBS/y/KqmrlIOsfrkppFAqwabE=", "goal"=>{"title"=>"Tavoite1", "description"=>"Kuvaus1", "celebration"=>"Juhlistus1"}, "progress"=>"0", "commit"=>"Luo tavoite", "action"=>"create", "controller"=>"goals", "project_id"=>"5"}
←[1m←[36mProject Load (0.0ms)←[0m ←[1mSELECT "projects".* FROM "projects" WHERE "projects"."id" = ? LIMIT 1←[0m [["id", 5]]
←[1m←[35m (0.0ms)←[0m begin transaction
←[1m←[36mSQL (1.0ms)←[0m ←[1mINSERT INTO "goals" ("celebration", "created_at", "description", "project_id", "title", "updated_at") VALUES (?, ?, ?, ?, ?, ?)←[0m [["celebration", "Juhlistus1"], ["created_at", "2014-10-30 10:56:05.533493"], ["description", "Kuvaus1"], ["project_id", 5], ["title", "Tavoite1"], ["updated_at", "2014-10-30 10:56:05.533493"]]
←[1m←[35m (108.8ms)←[0m commit transaction
←[1m←[36m (0.0ms)←[0m ←[1mbegin transaction←[0m
←[1m←[35m (0.0ms)←[0m commit transaction
←[1m←[36mProject Load (1.0ms)←[0m ←[1mSELECT "projects".* FROM "projects" WHERE "projects"."id" = ? LIMIT 1←[0m [["id", 5]]
Redirected to http://localhost:3000/projects/5
Completed 302 Found in 118ms (ActiveRecord: 110.8ms)
Tarkistin sen vielä konsolin kautta hakemalla kaikki tavoitteet tietokannasta.
irb(main):002:0> Goal.all
<snip>
#<Goal id: 13, title: "Tavoite1", description: "Kuvaus1", project_id: 5, created_at: "2014-10-30 10:56:05", updated_at: "2014-10-30 10:56:05", celebration: "Juhlistus1", progress: nil>]>
Ensin virhe oli ollut siinä, että en ollut sallinut progress-muuttujan tallentamista controllerin turvaosuudessa:
private
def goal_params
params.require(:goal).permit(:title, :description, :celebration, :progress)
end
Mutta syytä oli vielä jossain muuallakin. Mikä kummempaa, edistysnumeron päivitys onnistui olemassaolevaan tavoitteeseen mutta ei sen asettaminen nollaksi tavoitetta luodessa.
Googlailun jälkeen näytti siltä että en voi käyttää hidden_field_tagia, koska se ei ole jotenkin yhteydessä modeliin eli tietokantaan. Siitä seurasikin seuraava tenkkapoo. Mikä on hidden_fieldin oikea formaatti? Katsokaapa nimittäin tätä keskustelua: http://stackoverflow.com/questions/6636875/rails-hidden-field-undefined-method-merge-error
<%= f.hidden_field :service, "test" %>
<%= f.hidden_field :service, :value => "test" %>
<%= f.hidden_field :service %>
<%= f.hidden_field :service, value: "test" %>
Mitä näistä kuuluu käyttää? Dokumentaatiosta ei ole kovasti apua:
Examples
hidden_field(:signup, :pass_confirm)
<input type="hidden" id="signup_pass_confirm" name="signup[pass_confirm]" value="#{@signup.pass_confirm}" />
Mikä ihme tuo härpäke tuossa value-kohdassa on? Jos haluan vain arvoksi vaikka 0, miten saan sen siihen?
Ei auta kuin kokeilla.
<input id="goal_progress" name="goal[progress]" type="hidden" value="0" />
Jes! Nyt näyttää hyvältä!
Ensimmäinen haasteeni oli saada tavoitteenluontilomakkeeseen piilokenttä välittämään nolla controllerille. Lisäsin lomakkeeseen seuraavan rivin:
<%= hidden_field_tag 'progress', 0 %>
Näin sain aikaan html-koodin
<input id="progress" name="progress" type="hidden" value="0" />
kuten pitikin. Sitten tulikin tenkkapoo. Lomakkeeni kyllä lähetti hienosti progress-muuttujan, mutta controller ei tallentanut sitä tietokantaan.
Started POST "/projects/5/goals" for 127.0.0.1 at 2014-10-30 12:56:05 +0200
Processing by GoalsController#create as HTML
Parameters: {"utf8"=>"V", "authenticity_token"=>"JFtUcbAFJiAs8y08trBS/y/KqmrlIOsfrkppFAqwabE=", "goal"=>{"title"=>"Tavoite1", "description"=>"Kuvaus1", "celebration"=>"Juhlistus1"}, "progress"=>"0",
"commit"=>"Luo tavoite", "project_id"=>"5"}
DEBUG params inspect {"utf8"=>"V", "authenticity_token"=>"JFtUcbAFJiAs8y08trBS/y/KqmrlIOsfrkppFAqwabE=", "goal"=>{"title"=>"Tavoite1", "description"=>"Kuvaus1", "celebration"=>"Juhlistus1"}, "progress"=>"0", "commit"=>"Luo tavoite", "action"=>"create", "controller"=>"goals", "project_id"=>"5"}
←[1m←[36mProject Load (0.0ms)←[0m ←[1mSELECT "projects".* FROM "projects" WHERE "projects"."id" = ? LIMIT 1←[0m [["id", 5]]
←[1m←[35m (0.0ms)←[0m begin transaction
←[1m←[36mSQL (1.0ms)←[0m ←[1mINSERT INTO "goals" ("celebration", "created_at", "description", "project_id", "title", "updated_at") VALUES (?, ?, ?, ?, ?, ?)←[0m [["celebration", "Juhlistus1"], ["created_at", "2014-10-30 10:56:05.533493"], ["description", "Kuvaus1"], ["project_id", 5], ["title", "Tavoite1"], ["updated_at", "2014-10-30 10:56:05.533493"]]
←[1m←[35m (108.8ms)←[0m commit transaction
←[1m←[36m (0.0ms)←[0m ←[1mbegin transaction←[0m
←[1m←[35m (0.0ms)←[0m commit transaction
←[1m←[36mProject Load (1.0ms)←[0m ←[1mSELECT "projects".* FROM "projects" WHERE "projects"."id" = ? LIMIT 1←[0m [["id", 5]]
Redirected to http://localhost:3000/projects/5
Completed 302 Found in 118ms (ActiveRecord: 110.8ms)
Tarkistin sen vielä konsolin kautta hakemalla kaikki tavoitteet tietokannasta.
irb(main):002:0> Goal.all
<snip>
#<Goal id: 13, title: "Tavoite1", description: "Kuvaus1", project_id: 5, created_at: "2014-10-30 10:56:05", updated_at: "2014-10-30 10:56:05", celebration: "Juhlistus1", progress: nil>]>
Ensin virhe oli ollut siinä, että en ollut sallinut progress-muuttujan tallentamista controllerin turvaosuudessa:
private
def goal_params
params.require(:goal).permit(:title, :description, :celebration, :progress)
end
Mutta syytä oli vielä jossain muuallakin. Mikä kummempaa, edistysnumeron päivitys onnistui olemassaolevaan tavoitteeseen mutta ei sen asettaminen nollaksi tavoitetta luodessa.
Googlailun jälkeen näytti siltä että en voi käyttää hidden_field_tagia, koska se ei ole jotenkin yhteydessä modeliin eli tietokantaan. Siitä seurasikin seuraava tenkkapoo. Mikä on hidden_fieldin oikea formaatti? Katsokaapa nimittäin tätä keskustelua: http://stackoverflow.com/questions/6636875/rails-hidden-field-undefined-method-merge-error
<%= f.hidden_field :service, "test" %>
<%= f.hidden_field :service, :value => "test" %>
<%= f.hidden_field :service %>
<%= f.hidden_field :service, value: "test" %>
Mitä näistä kuuluu käyttää? Dokumentaatiosta ei ole kovasti apua:
Examples
hidden_field(:signup, :pass_confirm)
<input type="hidden" id="signup_pass_confirm" name="signup[pass_confirm]" value="#{@signup.pass_confirm}" />
Mikä ihme tuo härpäke tuossa value-kohdassa on? Jos haluan vain arvoksi vaikka 0, miten saan sen siihen?
Ei auta kuin kokeilla.
<%= f.hidden_field :progress, '0' %>
undefined method `merge' for "0":String
<%= f.hidden_field :progress, :value =>'0' %>
<input id="goal_progress" name="goal[progress]" type="hidden" value="0" />
Jes! Nyt näyttää hyvältä!
keskiviikko 15. lokakuuta 2014
Sekavat näkymät. Errorista eteenpäin
Mainitsin tuossa aiemmin jo controllerit ja modelit, niin kirjoitanpa vielä lisää niistä vieweistä. Näkymän tarkoitus on tosiaan vain tuoda data controllerista ihmisen ihasteltavaksi. Kuten get started -oppaassakin tehtiin, loin itsekin näkymiä sitä mukaa kun selaimelle tuli virhe puuttuvasta näkymästä. Se olikin lempivirheeni, koska tiesin heti mitä sille piti tehdä.
Controllerissa pitää olla kullekin käytetylle toiminnalle oma def-end, esim.
def show
@temptask = Temptask.find(params[:id])
@projects = Project.all
end
Sitten niillä pitää olla oma näkymänsä, eli app\views-hakemistossa kaikille controllereille on omat hakemistot ja niiden sisällä esimerkiksi \app\views\temptasks\show.html.erb
Näkymät kirjoitetaan template-kielellä, jossa html-koodin sekaan voi laittaa Railsin tulkkaamia pätkiä.
Esimerkiksi näin
<H1>Olet saanut aikaan tämän!</H1>
<p><%= @temptask.text %> (temptask id <%= @temptask.id %>)</p>
Tuossa sivun H1-otsikko on aina sama, mutta temptaskista riippuen seuraavaan kappaleeseen tulee eri teksti eli annetulla id:llä modelin kautta haetun temptaskin tekstikenttä. Id-kohdan olen laittanut vähän debuggaussyistä näkyviin.
Eniten tuskaa on aiheuttanut se mikä viewn mielestä on tunnettu muuttujan arvo ja mikä ei ja miten sen saa sieltä ulos.
Nämä asiat olen oppinut: 1) View tietää ne arvot, jotka controller on sille hakenut tai laskenut tai muuten muodostanut. Jos jokin ei näy, katse controlleriin. 2) Viewn tietämät arvot löytyvät paramsista. Olen käyttänyt sitä esim. näin:
<p><%= link_to 'Muokkaa', edit_project_goal_path(params[:project_id],@goal.id) %></p>
Sen mitä params pitää sisällään saa näkyviin seuraavan kaltaisella komennolla:
logger.debug "DEBUG params inspect #{params.inspect}"
Logger.debug siis printtaa viestejä serverin komentokehote-ikkunaan sinne kaikkien muiden printtien sekaan. Siksi laitoin selkeästi isoilla kirjaimilla tuon DEBUG rivin alkuun. Params:n varsinainen sisältö tulostuu #-merkistä alkavalla rimpsulla.
Joskus, itselleni vielä epäselvästä syystä, params:ssä on se haluttu arvo hashin sisällä. Eli jos normaalisti params:ssa on jutska1 => arvo1, jutska2 => arvo2, niin joskus se onkin jutska1 => {zydeemi1 => arvo3}. Tämän arvon saa ulos laittamalla nuo jutskat ja zydeemit peräkkäin omissa hakasuluissaan. Eli näin:
goal_id = params[:goal][:id]
Controllerissa pitää olla kullekin käytetylle toiminnalle oma def-end, esim.
def show
@temptask = Temptask.find(params[:id])
@projects = Project.all
end
Sitten niillä pitää olla oma näkymänsä, eli app\views-hakemistossa kaikille controllereille on omat hakemistot ja niiden sisällä esimerkiksi \app\views\temptasks\show.html.erb
Näkymät kirjoitetaan template-kielellä, jossa html-koodin sekaan voi laittaa Railsin tulkkaamia pätkiä.
Esimerkiksi näin
<H1>Olet saanut aikaan tämän!</H1>
<p><%= @temptask.text %> (temptask id <%= @temptask.id %>)</p>
Tuossa sivun H1-otsikko on aina sama, mutta temptaskista riippuen seuraavaan kappaleeseen tulee eri teksti eli annetulla id:llä modelin kautta haetun temptaskin tekstikenttä. Id-kohdan olen laittanut vähän debuggaussyistä näkyviin.
Eniten tuskaa on aiheuttanut se mikä viewn mielestä on tunnettu muuttujan arvo ja mikä ei ja miten sen saa sieltä ulos.
Nämä asiat olen oppinut: 1) View tietää ne arvot, jotka controller on sille hakenut tai laskenut tai muuten muodostanut. Jos jokin ei näy, katse controlleriin. 2) Viewn tietämät arvot löytyvät paramsista. Olen käyttänyt sitä esim. näin:
<p><%= link_to 'Muokkaa', edit_project_goal_path(params[:project_id],@goal.id) %></p>
Sen mitä params pitää sisällään saa näkyviin seuraavan kaltaisella komennolla:
logger.debug "DEBUG params inspect #{params.inspect}"
Logger.debug siis printtaa viestejä serverin komentokehote-ikkunaan sinne kaikkien muiden printtien sekaan. Siksi laitoin selkeästi isoilla kirjaimilla tuon DEBUG rivin alkuun. Params:n varsinainen sisältö tulostuu #-merkistä alkavalla rimpsulla.
Joskus, itselleni vielä epäselvästä syystä, params:ssä on se haluttu arvo hashin sisällä. Eli jos normaalisti params:ssa on jutska1 => arvo1, jutska2 => arvo2, niin joskus se onkin jutska1 => {zydeemi1 => arvo3}. Tämän arvon saa ulos laittamalla nuo jutskat ja zydeemit peräkkäin omissa hakasuluissaan. Eli näin:
goal_id = params[:goal][:id]
Reitit solmussa
Sitten yhteen hankalimmista mutta tärkeimmistä asioista: routes.rb tiedostoon ja reitteihin ylipäänsä.
Ensimmäinen muutos, jonka routes.rb tiedostoon tein, oli
root 'welcome#index'
Tämä tekee sen, että kun joku tulee nettisivun "juureen", hänet ohjataan welcome-controlleriin ja siellä index-actioniin.
Railsissa on eräänlaisia controllerien vakiotoimintoja. Toimintoja voi ja varmasti myöhemmin pitääkin tehdä myös itse, mutta vakiotoiminnot ovat helppokäyttöisiä ja hoitelevat paljon automaattisesti.
Toiminnot eli actionit ovat index, new, create, show, edit, update ja destroy.
Index on se mitä tehdään, kun käyttäjä haluaa nähdä kaikki tietyn tyyppiset jutskat, vaikka kaikki projektit.
New: luodaan uusi jutska mutta ei vielä tallenneta sitä mihinkään. Tätä tarvitaan vaikkapa siihen, kun näytetään sivu "Luo uusi projekti".
Create: luodaan uusi jutska ja tallennetaan se tietokantaan.
Show: näytetään yksi tietty jutska.
Edit: haetaan tietyn jutskan tiedot selaimelle muokkausta varten.
Update: tallennetaan muutokset tietokantaan.
Destroy: tuhotaan haluttu jutska.
Railsissa oikeaan toimintoon pääsee oikealla urlilla eli sillä mitä selaimen osoiterivillä lukee. Rails tulkitsee siitä mitä käyttäjä tai ohjelmoija haluaa. Nämä urlit saa tietoonsa kirjoittamalla komentoriville rake routes.
Siitä sujahtaa näkyville seuraavanlainen Railsin maagisesti koostama käsittämätön töräys:
Valitettavasti kyseessä on erittäin tärkeä lista, joka ymmärtäminen on ihan keskeistä.
Melko pitkään piti tukkaa nyhtää, mutta nyt tajuan mistä tuossa on kysymys. Otetaan yksi rivi esimerkiksi, vaikka se kaikkein pisin.
edit_project_goal_task GET /projects/:project_id/goals/:goal_id/tasks/:id/edit(.:format) tasks#edit
edit_project_goal_task on se Railsin apukomento, jota käytetään, kun halutaan päästä task-controllerin edit-toimintoon.
GET on se HTTP-verbi, jota käytetään. En tästä sen enempää vielä tiedä, mutta verbillä on merkitystä, kun sama url voikin viedä tapauksesta riippuen eri toimintoihin.
Sitten se url-osuus. Kun tuota edit_project_goal_task -apulaista kutsutaan, sen pitää tietää mikä projekti ja mikä tavoite ja mikä tehtävä, että se tietäisi luoda oikean urlin. Sille pitää jotakin kautta antaa ne puuttuvat tiedot eli :project_id, :goal_id ja :id. (Enimmät taisteluni Railsin kanssa olen käynyt juuri noista id:istä.)
Viimeinen sarake kertoo, mistä controllerista ja mistä toiminnosta on kysymys.
Ensimmäinen muutos, jonka routes.rb tiedostoon tein, oli
root 'welcome#index'
Tämä tekee sen, että kun joku tulee nettisivun "juureen", hänet ohjataan welcome-controlleriin ja siellä index-actioniin.
Railsissa on eräänlaisia controllerien vakiotoimintoja. Toimintoja voi ja varmasti myöhemmin pitääkin tehdä myös itse, mutta vakiotoiminnot ovat helppokäyttöisiä ja hoitelevat paljon automaattisesti.
Toiminnot eli actionit ovat index, new, create, show, edit, update ja destroy.
Index on se mitä tehdään, kun käyttäjä haluaa nähdä kaikki tietyn tyyppiset jutskat, vaikka kaikki projektit.
New: luodaan uusi jutska mutta ei vielä tallenneta sitä mihinkään. Tätä tarvitaan vaikkapa siihen, kun näytetään sivu "Luo uusi projekti".
Create: luodaan uusi jutska ja tallennetaan se tietokantaan.
Show: näytetään yksi tietty jutska.
Edit: haetaan tietyn jutskan tiedot selaimelle muokkausta varten.
Update: tallennetaan muutokset tietokantaan.
Destroy: tuhotaan haluttu jutska.
Railsissa oikeaan toimintoon pääsee oikealla urlilla eli sillä mitä selaimen osoiterivillä lukee. Rails tulkitsee siitä mitä käyttäjä tai ohjelmoija haluaa. Nämä urlit saa tietoonsa kirjoittamalla komentoriville rake routes.
Siitä sujahtaa näkyville seuraavanlainen Railsin maagisesti koostama käsittämätön töräys:
Valitettavasti kyseessä on erittäin tärkeä lista, joka ymmärtäminen on ihan keskeistä.
Melko pitkään piti tukkaa nyhtää, mutta nyt tajuan mistä tuossa on kysymys. Otetaan yksi rivi esimerkiksi, vaikka se kaikkein pisin.
edit_project_goal_task GET /projects/:project_id/goals/:goal_id/tasks/:id/edit(.:format) tasks#edit
edit_project_goal_task on se Railsin apukomento, jota käytetään, kun halutaan päästä task-controllerin edit-toimintoon.
GET on se HTTP-verbi, jota käytetään. En tästä sen enempää vielä tiedä, mutta verbillä on merkitystä, kun sama url voikin viedä tapauksesta riippuen eri toimintoihin.
Sitten se url-osuus. Kun tuota edit_project_goal_task -apulaista kutsutaan, sen pitää tietää mikä projekti ja mikä tavoite ja mikä tehtävä, että se tietäisi luoda oikean urlin. Sille pitää jotakin kautta antaa ne puuttuvat tiedot eli :project_id, :goal_id ja :id. (Enimmät taisteluni Railsin kanssa olen käynyt juuri noista id:istä.)
Viimeinen sarake kertoo, mistä controllerista ja mistä toiminnosta on kysymys.
Puuhastelua mallien kanssa
Loin myös vastaavat modelit. Halusin niiden riippuvan toisistaan, joten
tein taskiin goal_id-kentän ja goaliin project_id-kentän. Niin voisin
löytää kuhunkin tavoitteeseen liittyvät tehtävät ja kuhunkin projektiin
liittyvät tavoitteet. Loin mallit komentoriviltä, ja minun piti tehdä se muutamaan kertaan.
Lisäsin myös app/model-hakemistossa oleviin tiedostoihin tiedon siitä, millaisissa suhteissa ne ovat toisiinsa. Esim. app\models\task.rb tiedostoni näytti tältä:
class Task < ActiveRecord::Base
belongs_to :goal
end
ja app\models\project.rb
class Project < ActiveRecord::Base
has_many :goals
end
Näillä saa ohjeiden mukaan helpotettua esimerkiksi poistoa, kun ohjelma tietää mikä liittyy mihinkin. Onhan se itsellekin selkeyttävää, kun nämä laittaa paikoilleen.
Tietokantataulujen muoto generoituu tiedostoon db\schema.rb. Sieltä näkee minkä nimisiä sarakkeita sitä onkaan tullut luotua.
Taulujen luonnit ja muutokset tehdään migraatioilla. Antaisin ennemminkin nimeksi migreeni. Tämä osa-alue on jäänyt vielä melko hämäräksi. Idea on käsittääkseni se, että kukin muodon muutos tehdään ajamalla migraatiotiedosto, jonka voi myös perua. Menin itse niin solmuun noiden tiedostojen kanssa varsinkin kun menin käpälöimään käsin jotain mitä ilmeisesti ei olisi saanut muuttaa. Tiedostojen nimessä on aikaleima, jonka perusteella migraatiot ajetaan järjestyksessä.
Joka tapauksessa tietokannan hakiessa muotoaan minulle tuli tutuksi komentosarja
rake db:drop db:create db:migrate
joka tyhjentää tietokannat, luo ne uudelleen ja ajaa migraatiot. Joskus vielä ymmärrän tämänkin paremmin ja voin kirjoittaa siitä enemmän.
Lisäsin myös app/model-hakemistossa oleviin tiedostoihin tiedon siitä, millaisissa suhteissa ne ovat toisiinsa. Esim. app\models\task.rb tiedostoni näytti tältä:
class Task < ActiveRecord::Base
belongs_to :goal
end
ja app\models\project.rb
class Project < ActiveRecord::Base
has_many :goals
end
Näillä saa ohjeiden mukaan helpotettua esimerkiksi poistoa, kun ohjelma tietää mikä liittyy mihinkin. Onhan se itsellekin selkeyttävää, kun nämä laittaa paikoilleen.
Tietokantataulujen muoto generoituu tiedostoon db\schema.rb. Sieltä näkee minkä nimisiä sarakkeita sitä onkaan tullut luotua.
Taulujen luonnit ja muutokset tehdään migraatioilla. Antaisin ennemminkin nimeksi migreeni. Tämä osa-alue on jäänyt vielä melko hämäräksi. Idea on käsittääkseni se, että kukin muodon muutos tehdään ajamalla migraatiotiedosto, jonka voi myös perua. Menin itse niin solmuun noiden tiedostojen kanssa varsinkin kun menin käpälöimään käsin jotain mitä ilmeisesti ei olisi saanut muuttaa. Tiedostojen nimessä on aikaleima, jonka perusteella migraatiot ajetaan järjestyksessä.
Joka tapauksessa tietokannan hakiessa muotoaan minulle tuli tutuksi komentosarja
rake db:drop db:create db:migrate
joka tyhjentää tietokannat, luo ne uudelleen ja ajaa migraatiot. Joskus vielä ymmärrän tämänkin paremmin ja voin kirjoittaa siitä enemmän.
Valinnan paikka. Mitä ohjelmani tekee
Halusin siis tehdä oman ohjelman. Pieni ongelma oli ensin ratkaistavana - minun piti ensin keksiä mitä ohjelma tekisi.
Pienen pohdinnan jälkeen keksin loistavan idean, jossa pääsisin hyvin alkuun edellämainitulla Get Started -ohjeella. Tekisin ohjelman, jossa tietokantaan voisi lisätä projekteja, joiden alle voisi lisätä tavoitteita, joiden alle voisi lisätä tehtäviä. Tehtävät syötettäisiin irrallisina, ja ne liitettäisiin johonkin olemassaolevaan tavoitteeseen.
Siinäpä tavoitetta! Sain kuitenkin vähän vihiä siitä, millaisia controllereita tarvitsisin. Ohjeiden mukaan loin controllerit Project, Goal ja Task sekä Temptask. (Viimeksimainitun kanssa minun piti muuttaa nimeä, koska temp_task sekä TempTask aiheuttivat minulle ongelmia Railsin omatoimisen tiedoston- ja muun tauhkan luomisen kanssa.) Controllerit tallentuvat app/controllers -hakemistoon.
Pienen pohdinnan jälkeen keksin loistavan idean, jossa pääsisin hyvin alkuun edellämainitulla Get Started -ohjeella. Tekisin ohjelman, jossa tietokantaan voisi lisätä projekteja, joiden alle voisi lisätä tavoitteita, joiden alle voisi lisätä tehtäviä. Tehtävät syötettäisiin irrallisina, ja ne liitettäisiin johonkin olemassaolevaan tavoitteeseen.
Siinäpä tavoitetta! Sain kuitenkin vähän vihiä siitä, millaisia controllereita tarvitsisin. Ohjeiden mukaan loin controllerit Project, Goal ja Task sekä Temptask. (Viimeksimainitun kanssa minun piti muuttaa nimeä, koska temp_task sekä TempTask aiheuttivat minulle ongelmia Railsin omatoimisen tiedoston- ja muun tauhkan luomisen kanssa.) Controllerit tallentuvat app/controllers -hakemistoon.
Rohkaistuminen. Koodin kopiointi on tylsää
Nyt siis oli edessä ensimmäisen applikaation tekeminen. Rails on siitä hyvä systeemi, että se tekee ohjelmoijan puolesta paljon rutiinihommia ja rohkaisee hyvään ohjelmointityyliin (tai näi ainakin mainoslause sanoo). Joka tapauksessa se luo paljon hakemistoja ja tiedostoja, joiden käyttötarkoituksesta ei ole alussa hajuakaan.
Näin kävi myös kun lähdin seuraamaan http://guides.rubyonrails.org/getting_started.html ohjeita ja loin ensimmäisen controllerini. En vielä siinä vaiheessa tiennyt yhtään, mikä controller on.
Mieheni, joka on ohjelmoinut jonkin verran Djangolla, joka on samantapainen alusta kuin Rails, selitti minulle miten asia menee, ja alkoihan se jostain muustakin yhteydestä muistua mieleen.
Applikaatiossa on siis kolme kerrosta: view, controller ja model. (Ja sitten se varsinainen tietokanta pohjalla). Ne ovat toistensa kanssa tekemisissä sillä tavalla, että view näyttää nätisti tiedon, jonka controller on jollain logiikalla kursinut kokoon ja hakenut modelin kautta tietokannasta. Model on tietokannan helppokäyttöinen ohjaamo. Minulla ei ole aavistustakaan mitä nämä termit ovat suomeksi, mutta ehkä jossain vaiheessa sen opin.
Joka tapauksessa se ohjelman varsinainen äly on controllerissa. Käyttäjä pyytää ohjelmaa tekemään jotain, ja pyyntö menee selaimen osoiterivin kautta controlleriin, joka tekee jotain ja palauttaa käyttäjälle tuloksen.
Kyllästyin ohjeiden seuraamiseen ja koodin kopioimiseen varsin äkkiä ja halusin tehdä ihan oman ohjelman.
Näin kävi myös kun lähdin seuraamaan http://guides.rubyonrails.org/getting_started.html ohjeita ja loin ensimmäisen controllerini. En vielä siinä vaiheessa tiennyt yhtään, mikä controller on.
Mieheni, joka on ohjelmoinut jonkin verran Djangolla, joka on samantapainen alusta kuin Rails, selitti minulle miten asia menee, ja alkoihan se jostain muustakin yhteydestä muistua mieleen.
Applikaatiossa on siis kolme kerrosta: view, controller ja model. (Ja sitten se varsinainen tietokanta pohjalla). Ne ovat toistensa kanssa tekemisissä sillä tavalla, että view näyttää nätisti tiedon, jonka controller on jollain logiikalla kursinut kokoon ja hakenut modelin kautta tietokannasta. Model on tietokannan helppokäyttöinen ohjaamo. Minulla ei ole aavistustakaan mitä nämä termit ovat suomeksi, mutta ehkä jossain vaiheessa sen opin.
Joka tapauksessa se ohjelman varsinainen äly on controllerissa. Käyttäjä pyytää ohjelmaa tekemään jotain, ja pyyntö menee selaimen osoiterivin kautta controlleriin, joka tekee jotain ja palauttaa käyttäjälle tuloksen.
Kyllästyin ohjeiden seuraamiseen ja koodin kopioimiseen varsin äkkiä ja halusin tehdä ihan oman ohjelman.
Tilaa:
Blogitekstit (Atom)
