Skip to content

mallivastaus

Matti Luukkainen edited this page Mar 14, 2017 · 1 revision

Erillistä kokeen palautustilaisuutta ei järjestetä. Oman kokeen arvostelusta voi kysyä suoraan kunkin tehtävän korjaajalta joko emailitse tai irkissä:

tehtävä 1

Sovelluksen toiminta osoitteeseen http://localhost:3000/authors/1 HTTP GET -pyynön yhteydessä:

  1. routes.rb:n määrittelyn get '/authors/:id', to:'authors#show' takia pyynnön hoitaa AuthorsController-luokan metodi show.
  2. routes.rb:n määrittelyn ansiosta urlin resurssin yksilöivä osa asetetaan params-hashin avaimen :id arvoksi
  3. kontrolleri hakee tietokannasta tunnistetta vastaavan resurssin
  4. tietokantahaku tapahtuu resurssia vastaavan model-luokan Department luokkametodin find avulla
  5. haettua resurssia käsitellään Author-luokan instanssina
  6. kontrolleri asettaa haetun resurssin instanssimuuttujaan @author
  7. kontrollerin lopussa suoritetaan oletusarvoisen näkymätemplaten views/authors/show.html.erb renderöinti
  8. template 'näkee' kontrollerin asettaman instanssimuuttujan @author kautta sivua vastaavan laitoksen
  9. kirjailijaa vastaava model-luokka on määritelty sisältämään joukon Book-luokan olioita (has many...), joihin laitos pääsee käsiksi metodin booksi avulla
  10. näkymätemplate renderöi sivulle (kirjailijan nimen ja maan lisäksi) each-iteraattorin avulla läpikäyden linkit kirjailijan kirjoihin link_to-metodia käyttäen
  11. näkymätemplaten renderöinnin seurauksena syntyy HTML-sivu, joka palautetaan selaimelle yhdessä HTTP-statuskoodin (200) kanssa

Täydet pisteet jos suunilleen jokainen vaihe oli mainittu tai kävi vastauksesta ilmi. Noin -0.5p jokaisen oleellisen vaiheen maininnan puutteesta.

tehtävä 2

  1. selain tekee HTTP POST -pyynnön osoitteeseen /authors. Pyynnön mukana välittyy tieto luotavan kirjailijan laitoksen nimestä ja maasta
  2. routes.rb:n määrittelyn post '/authors', to:'authors#create' perusteella kutsutaan AuthorsController:in metodia create
  3. kontrolleri pääsee käsiksi lomakkeen lähettämiin tietoihin params-muuttujan avulla, käyttäen require- ja permit-metodeja, käytännössä tieto on hash muotoa { :name => "Arto Hellas", country: "Finland" }
  4. kontrolleri luo uuden Author-olion lomakkeen tiedoilla ja tallettaa sen muuttujaan @author
  5. kontrolleri pyytää olioa tallentumaan kutsumalla sen metodia save
  6. tallennuksen yhteydessä suoritetaan modelin määrittelemät validoinnit, eli tarkistetaan onko nimi uniikki ja pituudeltaan vähintään 3 merkkiä ja maa epätyhjä

jos talletus onnistuu eli olio on validi:

  1. save palauttaa toden arvon
  2. uudelleenohjataan käyttäjän selain kaikkien kirjailijoiden sivulle, käytännössä tämä tarkoittaa että HTTP-kutsuun vastataan statuskoodilla 302 ja tiedolla siitä, mihin urliin selaimen tulee tehdä HTTP GET
  3. selain siis tekee GET-pyynnön authorien sivulle. Sivulla näytetään myös kontrollerin määrittelemä 'flash'-viesti

jos talletus ei onnistu eli olio on epävalidi:

  1. save palauttaa epätoden arvon
  2. kirjailijan luontiin tarkoitettu lomake 'new' renderöidään uudelleen
  3. validoinnin yhteydessä olioon on liitetty muuttuja error, jonka perusteella lomakkeelle renderöityvät validoinnin virheviestit
  4. virheviesteillä varustettu lomake palautetaan pyynnön tehneelle selaimelle

pisteytys:

  • POST ja reititys oikealle metodille 1p
  • formin tietojen aksessointi ja olion luominen 0.5p
  • validointi (millä perusteella ja milloin) 1p
  • redirect jos validi 1p
    • piste edellytti että selitetään mitä redirectaus tarkoittaa
  • renderöinti virheilmoituksilla 0.5p

tehtävä 3

Mainittu sivun ongelmia (0.5p jokaisesta), joita olivat esimerkiksi

  • Authorin kirjat ladataan laiskasti, joten jokaisen authorin kohdalla joudutaan tekemään monta SQL kyselyä. Tätä kutsutaan ns N+1 ongelmaksi.
  • total_pages-metodissa käytetty books.inject hakee ensin kaikki kirjat muistiin yhdellä kyselyllä, ja sitten iteroi niitä Rubyssä. Tämä on hidasta, ja sen voisi tehdä tietokanta-tasolla

Esitetty ratkaisut mainittuihin ongelmiin ja mahdolliset ongelmat ratkaisuissa (1p), ja ainakin yhdestä annettu konkreettinen koodiesimerkki (1p). Näitä olivat mm.

  • Kirjat voi ladata "ahneesti" käyttämällä Railsin includes-metodia: @authors = Author.includes(:books).all

  • Sivulla voi käyttää palvelinpuolen tai selainpuolen välimuistia, esim näkymässä

      <% @authors.each do |author| %>
        <% cache author do %>
          <%= render author %>
        <% end %>
      <% end %>
    

    Välimuistin invalidaatio on kuitenkin ikuinen ongelma.

  • inject-käskyn voi korvata esim

      def total_pages
        books.sum(:pages)
      end
  • total_pagesin voisi myös tehdä uutena sarakkeena tietokantaan, jolloin sitä pitäisi päivittää aina kun authorille lisätään kirjoja.

  • Paginaatio jakaisi authorit useammalle sivulle, jolloin yhden sivun lataus ei olisi kovin hidas. Tällöin jokin hakutoiminto olisi ehkä paikallaan, koska ei pysty enää ctrl+f.

tehtävä 4

Pisteitä sai seuraavasti:

  • 1p: luotu esim scaffoldilla kerho niin että näkyy attribuutit, esim
  • rails g scaffold Genre name:string description:string
  • TAI näytetty migraatio joka luo sen, jossa on create table
  • TAI selitetty selkeästi millaiset attribuutit genrellä on, ja kerrottu että sen voi luoda esim scaffoldilla tai migraatiolla
  • tajuttu, että pitää tehdä liitostaulu 0,5p
  • liitostaulussa foreign keyt author_id ja genre_id 0,5p
  • kelpaa jos teki scaffoldilla tai migraatiolla, tai kertoi selkeästi että idt tarvitaan
  • has_many välitauluolio ja välitauluissa belongs_to oikein 1p

Jos kirjoitti jotain, mikä ei ole totta, lähti pisteitä

tehtävä 5

  • On tehty metodi joka palauttaa halutun kokonaisluvun (vuoden), eikä esim book oliota (1p)
    • Käytetty jotain olemassaolevia käskyjä, joiden syntaksi on ainakin suurinpiirtein oikein
    • Haettu nimenomaan pienin julkaisuvuosi eikä esim ensimmäisen kirjan julkaisuvuosi.
  • Tehty testi, jossa
    • Luodaan ainakin yksi author ja kaksi book oliota, jotka on julkaistu eri aikoihin. (1.5p)
    • Tarkistetaan, että metodin palauttama vuosi on luoduista kirjoista sen kirjan vuosi, joka on aiemmin. (0.5p)

Esimerkki hyvästä (3p) vastauksesta

  # app/models/author.rb
  def first_publication_at
    books.order(:published).first.published
  end

  # spec/models/authors_spec.rb
  it "returns correct year for first publication" do
    author = Author.create name: "Robert Martin", country: "USA"
    author.books.create title: "TestBook", published: 2012
    author.books.create title: "GoodBook", published: 1998

    first_publication = author.first_publication_at
    expect(first_publication).to eq 1998
  end
Clone this wiki locally