Übungen zu Datenbanksysteme

Institut für Informatik
Prof. Dr. Oliver Vornberger
Nils Haldenwang, M.Sc.
Universität Osnabrück, 16.06.2015
http://www-lehre.inf.uos.de/~dbs
Testat bis 24.06.2015, 14:00 Uhr
Übungen zu Datenbanksysteme
Sommersemester 2015
Blatt 8: Ruby on Rails
Technische Hinweise:
Auf dem Server project2.informatik.uos.de (Einloggen mit RZ-Daten per SSH) erhalten Sie Zugang zu Ruby mit dem Kommando rvm use 2.2.2 auf der Konsole. Danach können Sie mit rails new mein_projekt -d mysql ein neues Rails-Projekt mit MySQLDatenbankanbindung anlegen. Fügen Sie anschließend in die Datei Gemfile die Zeile gem
’therubyracer’ ein und führen Sie das Kommando bundle auf der Konsole in Ihrem neuen
Rails-Projektverzeichnis aus.
Konfigurieren Sie den Zugang zur Datenbank über die Datei config/database.yml. Nutzen Sie die Datenbank, die mit Ihrem Nutzernamen von Blatt 5 auf dbs2 zur Verfügung steht. Ändern Sie die Zeile socket: /var/run/mysql/mysqld.sock zu host:
dbs2.informatik.uos.de und passenden Sie die übrigen Parameter in der Umgebung
development entsprechend an.
Wenn Sie auf project2 einen Rails-Server starten, müssen Sie mit -p [portnr] eine Portnr.
angeben, da nur der erste Server, der auf dbs gestartet wird, die Standardportnr. 3000 verwenden
kann. Verwenden Sie am besten eine Portnr. zwischen 3000 und 4000. Weiterhin muss der gestartete
Server an die IP-Adresse von project2 gebunden werden, dies geschieht mittels des flags -b IP.
Das Startkommando für den Server lautet also:
rails s -b 131.173.32.33 -p [portnr]. Ihre Rails-Applikation erreichen Sie im Webbrowser anschließend unter: http://project2.informatik.uos.de:[portnr]
Alle Aufgaben müssen mit Ruby Version >= 2.2.2 und Rails Version >= 4.2.1 bearbeitet und im Testat
vorgeführt werden.
Aufgabe 8.1: Ruby (15 Punkte)
Schreiben Sie ein kurzes Ruby-Script,
romeo_and_juliet.txt zählt.
das
die
Wörter
in
der
beiliegenden
Datei
Wenn Ihr Script mit ruby meinscript.rb ausgeführt wird, soll es die beliegende Datei einlesen.
Extrahieren Sie (etwa mit einem regulären Ausdruck oder einer anderen geeigneten Methode) die
einzelnen Wörter und legen Sie einen Hash an, der als Schlüssel ein Wort und als Wert die Anzahl
seines Vorkommens enthält.
Sortieren Sie schließlich den Hash derart, dass Sie auf der Konsole die 50 häufigsten Wörter mit ihrer
Anzahl ausgeben bevor Ihr Script beendet ist.
Musterlösung:
#!/usr/bin/env ruby
# Methode um Wörter zu extrahieren
def words(str)
str.split(/[\W]*\s[\W]*/)
end
#Hash
wordcount = Hash.new(0)
#Datei einlesen
File.open("romeo_and_juliet.txt", "r") do |f|
while !f.eof? && line = f.readline
words(line).each do |word|
#Hashwert erhöhen, wenn der String nicht leer
wordcount[word] += 1 unless word.empty?
end
end
end
#Sortieren
sorted = wordcount.sort_by { |elem| -elem[1] }
#Ausgeben
sorted[0...50].each do |elem|
puts "#{elem[0]}: #{elem[1]}"
end
Aufgabe 8.2: Mensa-Speiseplan mit Ruby on Rails (30 Punkte)
Erstellen Sie eine Rails-Applikation für einen Mensa-Speiseplan.
Modellieren Sie dafür einen Tagesplan, der über ein Datum verfügt sowie einen Event-Text (z.B Pizzatag). An jedem Tag kann es beliebig viele Speisen geben, die durch eine Beschreibung, einen Preis
für Studenten und einen für Gäste ausgezeichnet sind. Weiterhin gehört jede Speise zu einer Kategorie
(Hauptkomponente, Eintopf, etc). Beachten Sie, dass eine Speise mehreren Tagesplänen zugeordnet
sein kann.
Arbeiten Sie mit Scaffolds und Migrations, um Ihre grundlegende Applikation weitestgehend zu erzeugen. Passen Sie Ihre Models ggf. so an, dass Sie auf der Ruby-Konsole rails c an einem
Tagesplan-Objekt mit einem Methodenaufruf ein Array von Speisen-Objekten, das zu diesem Tag
gehört, zurückgeliefert bekommen.
Fügen Sie einige geeignete Beispieldaten zum Testen in Ihre Applikation ein. Geben Sie in Ihren
Models in Kommentarform an, was Sie sich bei den Relationen und Entitäten gedacht haben und
modellieren möchten.
2
Musterlösung:
Siehe Anhang. Workflow:
rails new mensa -d mysql
rails generate scaffold Plan date:date event:string
rails generate scaffold Dish description:string price_student:float
price_guest:float category:string
rails generate migration create_dishes_plans
class CreateDishesPlans < ActiveRecord::Migration
def change
create_table "dishes_plans" do |t|
t.references :dish
t.references :plan
end
end
end
Anpassen der Beziehungen in den Models:
has_and_belongs_to_many :plans
has_and_belongs_to_many :dishes
Aufgabe 8.3: N:M Beziehungen in Scaffolds (15 Punkte)
Bearbeiten Sie Ihr Model und die zugehörige Formular-View des Tagesplans derart, dass
dort eine Menge von in der Datenbank vorhandenen Speisen auf der HTML-Seite ausgewählt und zugewiesen werden kann. Betrachten Sie dazu die Dokumentation der Methode
collection_select im Modul ActionView::Helpers::FormOptionsHelper. Verändern Sie auch die show.html.erb-View so, dass die Speisen des Tages in einer Liste angezeigt
werden.
Musterlösung:
In show.html.erb
<p>
<b>Dishes:</b>
<ul>
<% @plan.dishes.each do |d| %>
<li><%= d.description %></li>
<% end %>
</ul>
</p>
3
In _form.html.erb, nachdem dish_ids im PlansController in der Methode plan_params
mittels :dish_ids => [] gewhitelisted wurde. OBACHT: Wer die Musterlösung vom letzten
Durchgang abgeschrieben hat, hat das nicht, das kam erst mit Rails 4.
<div class="field">
<%= f.label :dishes %>
<%= f.collection\_select(:dish\_ids, Dish.all, :id, :description,
{selected: @plan.dish\_ids, include_blank: true}, {multiple: true}) %>
</div>
Aufgabe 8.4: Wochenübersicht (20 Punkte)
Erzeugen Sie einen neuen Controller mit einer einzigen Action, die für einen übergebenen Tag oder
den aktuellen, sollte keiner übergeben worden sein, den Speiseplan für diesen und die darauf folgenden sechs Tage in geeigneter Form ausgibt.
Musterlösung:
Controller:
class WeekController < ApplicationController
def index
start_date = params[:date] ? Date.parse(params[:date]) : Date.today
end_date = start_date + 6
@plans = Plan.where(["date < ? && date >= ?", end_date, start_date])
end
end
View:
<h1>Speiseplan</h1>
<% @plans.each do |d| %>
<h2><%= d.date %> <%= d.event %></h2>
<ul>
<% d.dishes.each do |e| %>
<li><%= e.description %> (<%= e.category %>), Studenten:
<%= e.price_student %>; G&auml;ste: <%= e.price_guest %></li>
<% end %>
</ul>
<% end %>
Aufgabe 8.5: Fragen zur Veranstaltung (20 Punkte)
Beantworten Sie Ihrer Tutorin/Ihrem Tutor Fragen zur Veranstaltung.
4