35
Nils Haldenwang, B.Sc. Gastvortrag Datenbanksysteme: Ruby on Rails Institut für Informatik AG Medieninformatik 1

Gastvortrag Datenbanksysteme: Ruby on Railsdbs/2015/PDF/dbs2015-06-16.pdf5 Migrations • Ruby DSL zur Definition und Manipulation des Datenbankschemas • Datenbankunabhängig (in

  • Upload
    others

  • View
    1

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Gastvortrag Datenbanksysteme: Ruby on Railsdbs/2015/PDF/dbs2015-06-16.pdf5 Migrations • Ruby DSL zur Definition und Manipulation des Datenbankschemas • Datenbankunabhängig (in

Nils Haldenwang, B.Sc.

Gastvortrag Datenbanksysteme:

Ruby on Rails

Institut für InformatikAG Medieninformatik1

Page 2: Gastvortrag Datenbanksysteme: Ruby on Railsdbs/2015/PDF/dbs2015-06-16.pdf5 Migrations • Ruby DSL zur Definition und Manipulation des Datenbankschemas • Datenbankunabhängig (in

Ruby on Rails

Models mit ActiveRecord

2

Page 3: Gastvortrag Datenbanksysteme: Ruby on Railsdbs/2015/PDF/dbs2015-06-16.pdf5 Migrations • Ruby DSL zur Definition und Manipulation des Datenbankschemas • Datenbankunabhängig (in

Ruby on Rails

Model: ORM

Idee: Repräsentiere die Tabelle durch eine Klasse und die Zeilen durch einzelne Instanzen.

id first_name last_name age

1 Nils Haldenwang 252 Luke Skywalker 42

Tabelle: users Klasse: User

snake_case

pluralisierter snake_case

Page 4: Gastvortrag Datenbanksysteme: Ruby on Railsdbs/2015/PDF/dbs2015-06-16.pdf5 Migrations • Ruby DSL zur Definition und Manipulation des Datenbankschemas • Datenbankunabhängig (in

Migrations

4Ruby on Rails

Page 5: Gastvortrag Datenbanksysteme: Ruby on Railsdbs/2015/PDF/dbs2015-06-16.pdf5 Migrations • Ruby DSL zur Definition und Manipulation des Datenbankschemas • Datenbankunabhängig (in

5

Migrations• Ruby DSL zur Definition und Manipulation des

Datenbankschemas

• Datenbankunabhängig (in gewissem Rahmen)

• Inkrementelle Entwicklung der Datenbank

• Kann mit in die Versionskontrolle eingecheckt werden

• Automatische Versionierung

• Gesamtschema in db/schema.rb

Ruby on Rails

Page 6: Gastvortrag Datenbanksysteme: Ruby on Railsdbs/2015/PDF/dbs2015-06-16.pdf5 Migrations • Ruby DSL zur Definition und Manipulation des Datenbankschemas • Datenbankunabhängig (in

Beispiel: Tabelle erstellen

6

class CreateUsers < ActiveRecord::Migration

def up create_table :users do |t| t.string :first_name t.string :last_name

t.timestamps end end

def down drop_table :users endend

Ruby on Rails

Anpassungdes Schemas

Anpassungrückgängigmachen

Page 7: Gastvortrag Datenbanksysteme: Ruby on Railsdbs/2015/PDF/dbs2015-06-16.pdf5 Migrations • Ruby DSL zur Definition und Manipulation des Datenbankschemas • Datenbankunabhängig (in

Ruby on Rails

class User < ActiveRecord::Baseend

u = User.new first_name: "Obi-Wan", last_name: "Kenobi"u.persisted? # => falseu.saveu.persisted? # => trueputs "#{u.first_name}, #{u.last_name}"# => Obi-Wan Kenobi

obi_wan = User.find_by_first_name("Obi-Wan")puts obi_wan.last_name # => Kenobi

Model: Userapp/models/user.rb DRY

Page 8: Gastvortrag Datenbanksysteme: Ruby on Railsdbs/2015/PDF/dbs2015-06-16.pdf5 Migrations • Ruby DSL zur Definition und Manipulation des Datenbankschemas • Datenbankunabhängig (in

Ruby on Rails

Query-API

8

Page 9: Gastvortrag Datenbanksysteme: Ruby on Railsdbs/2015/PDF/dbs2015-06-16.pdf5 Migrations • Ruby DSL zur Definition und Manipulation des Datenbankschemas • Datenbankunabhängig (in

Where-Clauses

9

User.create name: "Nils", age: 24User.create name: "Luke", age: 42

User.where(name: "Nils")User.where("name = ?", "Nils")User.where("name = :name", name: "Nils")

User.where(name: "Nils", age: 24)User.where(name: "Nils").where(age: 24)User.where("name = ? AND age = ?", "Nils", 24)

User.where("name = ? OR age = ?", "Nils", 42)

User.where(name: ["Nils", "Luke"]).order("name ASC")

User.where("name LIKE 'L%'")

Page 10: Gastvortrag Datenbanksysteme: Ruby on Railsdbs/2015/PDF/dbs2015-06-16.pdf5 Migrations • Ruby DSL zur Definition und Manipulation des Datenbankschemas • Datenbankunabhängig (in

SQL-Injections

10

User.where("name = #{params[:name]}")

Robert’); DROP TABLE Students; --

Obacht!

Page 11: Gastvortrag Datenbanksysteme: Ruby on Railsdbs/2015/PDF/dbs2015-06-16.pdf5 Migrations • Ruby DSL zur Definition und Manipulation des Datenbankschemas • Datenbankunabhängig (in

Ruby on Rails

Associations

11

Page 12: Gastvortrag Datenbanksysteme: Ruby on Railsdbs/2015/PDF/dbs2015-06-16.pdf5 Migrations • Ruby DSL zur Definition und Manipulation des Datenbankschemas • Datenbankunabhängig (in

1:1-Beziehung: Definition

12

class Avatar < ActiveRecord::Base belongs_to :userend

class User < ActiveRecord::Base has_one :avatarend

Fremdschlüssel: user_id

Page 13: Gastvortrag Datenbanksysteme: Ruby on Railsdbs/2015/PDF/dbs2015-06-16.pdf5 Migrations • Ruby DSL zur Definition und Manipulation des Datenbankschemas • Datenbankunabhängig (in

1:1-Beziehung: Anwendung

13

u = User.create name: 'Nils'u.avatar # => nila = Avatar.new url: 'foo.jpeg'a.persisted? # => falseu.avatar = aa.persisted? # => true

u.avatar = Avatar.new url: 'bar.jpeg'

Avatar.all# => [# #<Avatar id: 1, url: "foo.jpeg", user_id: nil>,# #<Avatar id: 2, url: "bar.jpeg", user_id: 1># ]

Page 14: Gastvortrag Datenbanksysteme: Ruby on Railsdbs/2015/PDF/dbs2015-06-16.pdf5 Migrations • Ruby DSL zur Definition und Manipulation des Datenbankschemas • Datenbankunabhängig (in

Abhängigkeiten

14

class Avatar < ActiveRecord::Base belongs_to :userend

class User < ActiveRecord::Base has_one :avatar, dependent: :destroyend

Page 15: Gastvortrag Datenbanksysteme: Ruby on Railsdbs/2015/PDF/dbs2015-06-16.pdf5 Migrations • Ruby DSL zur Definition und Manipulation des Datenbankschemas • Datenbankunabhängig (in

1:n-Beziehung: Definition

15

class Article < ActiveRecord::Base belongs_to :userend

class User < ActiveRecord::Base has_many :articlesend

Fremdschlüssel: user_id

Page 16: Gastvortrag Datenbanksysteme: Ruby on Railsdbs/2015/PDF/dbs2015-06-16.pdf5 Migrations • Ruby DSL zur Definition und Manipulation des Datenbankschemas • Datenbankunabhängig (in

1:n-Beziehung: Anwendung

16

u = User.firstu.articles # => nilu.articles.new title: "Title"# => #<Article id: nil, title: "Title", user_id: 1>u.saveu.articles.first# => => #<Article id: 1, title: "Title", user_id: 1>

u.articles << Article.new( title: "Another Title" )u.articles.count # => 2

u.articles.delete Article.find(1)u.articles.count # => 1

u.articles.clearu.articles.count # => 0

Article.count # => 2

Page 17: Gastvortrag Datenbanksysteme: Ruby on Railsdbs/2015/PDF/dbs2015-06-16.pdf5 Migrations • Ruby DSL zur Definition und Manipulation des Datenbankschemas • Datenbankunabhängig (in

n:m-Beziehung: Definition

17

class Article < ActiveRecord::Base has_and_belongs_to_many :tagsend

class Tag < ActiveRecord::Base has_and_belongs_to_many :articlesend

class CreateArticlesTags < ActiveRecord::Migration def change create_table :articles_tags, id: false do |t| t.references :article, null: false t.references :tag, null: false end end

Sortiert

Page 18: Gastvortrag Datenbanksysteme: Ruby on Railsdbs/2015/PDF/dbs2015-06-16.pdf5 Migrations • Ruby DSL zur Definition und Manipulation des Datenbankschemas • Datenbankunabhängig (in

Ruby on Rails

Validations

18

ActiveRecordGrundlagen

Page 19: Gastvortrag Datenbanksysteme: Ruby on Railsdbs/2015/PDF/dbs2015-06-16.pdf5 Migrations • Ruby DSL zur Definition und Manipulation des Datenbankschemas • Datenbankunabhängig (in

Validations: Grundlagen

19

class User < ActiveRecord::Base validates_numericality_of :age validates_presence_of :nameend

u = User.new age: "foo"u.valid? # => falseu.errors[:age] # => "is not a number"u.errors[:name] # => "can't be blank"

Page 20: Gastvortrag Datenbanksysteme: Ruby on Railsdbs/2015/PDF/dbs2015-06-16.pdf5 Migrations • Ruby DSL zur Definition und Manipulation des Datenbankschemas • Datenbankunabhängig (in

Validations: Parameter

20

validates_presence_of :name, message: "Y u no use name?"

validates_numericality_of :age, on: :create

validates_length_of :name, within: 6..42

validates :name, presence: true, length: { minimum: 6 }, uniqueness: true

Page 21: Gastvortrag Datenbanksysteme: Ruby on Railsdbs/2015/PDF/dbs2015-06-16.pdf5 Migrations • Ruby DSL zur Definition und Manipulation des Datenbankschemas • Datenbankunabhängig (in

Validierung mit Methode

21

class Feed < ActiveRecord::Base validate :valid_feed_url

protected def valid_feed_url result = Feedzirra::Feed.fetch_and_parse(self.url) if result.nil? || result.kind_of?(Fixnum) errors.add(:url, "The feed url was not valid.") end endend

Page 22: Gastvortrag Datenbanksysteme: Ruby on Railsdbs/2015/PDF/dbs2015-06-16.pdf5 Migrations • Ruby DSL zur Definition und Manipulation des Datenbankschemas • Datenbankunabhängig (in

Ruby on Rails

Callbacks

22

ActiveRecordGrundlagen

Page 23: Gastvortrag Datenbanksysteme: Ruby on Railsdbs/2015/PDF/dbs2015-06-16.pdf5 Migrations • Ruby DSL zur Definition und Manipulation des Datenbankschemas • Datenbankunabhängig (in

Callback-Registrierung

23

class Beethoven < ActiveRecord::Base before_destroy :last_words

protected def last_words logger.info "Friends applaud, the comedy is over." endend

class Beethoven < ActiveRecord::Base before_destroy do logger.info "Friends applaud, the comedy is over." end

before_save(on: create) do logger.info "Here we go." endend

Page 24: Gastvortrag Datenbanksysteme: Ruby on Railsdbs/2015/PDF/dbs2015-06-16.pdf5 Migrations • Ruby DSL zur Definition und Manipulation des Datenbankschemas • Datenbankunabhängig (in

Mögliche Callbacks

24

• before_validation, before_validation_on_create

• after_validation, after_validation_on_create

• before_save

• before_create, after_create

• before_destroy, after_destroy

Page 25: Gastvortrag Datenbanksysteme: Ruby on Railsdbs/2015/PDF/dbs2015-06-16.pdf5 Migrations • Ruby DSL zur Definition und Manipulation des Datenbankschemas • Datenbankunabhängig (in

Beispiel: Geocoding

25

class Address < ActiveRecord::Base include GeoKit::Geocoders

before_save :geolocate validates_presence_of :street, :city, :state, :zip

def to_s "#{street} #{city} #{state} #{zip}" end

protected def geolocate res = GoogleGeocoder.geocode(to_s) self.lattitude = res.lat self.longitude = res.lng endend

Page 26: Gastvortrag Datenbanksysteme: Ruby on Railsdbs/2015/PDF/dbs2015-06-16.pdf5 Migrations • Ruby DSL zur Definition und Manipulation des Datenbankschemas • Datenbankunabhängig (in

Verarbeitung abbrechen

26

def geolocate res = GoogleGeocoder.geocode(to_s) if res.success self.lattitude = res.lat self.longitude = res.lng else errors[:base] = "Geocoding failed. Please check address." false endend

Abbruch der Verarbeitung, wenn ein Callback false liefert

Page 27: Gastvortrag Datenbanksysteme: Ruby on Railsdbs/2015/PDF/dbs2015-06-16.pdf5 Migrations • Ruby DSL zur Definition und Manipulation des Datenbankschemas • Datenbankunabhängig (in

Views mit HTML & ERB

27Ruby on Rails

Page 28: Gastvortrag Datenbanksysteme: Ruby on Railsdbs/2015/PDF/dbs2015-06-16.pdf5 Migrations • Ruby DSL zur Definition und Manipulation des Datenbankschemas • Datenbankunabhängig (in

HTML-Gerüst

28

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"><html> <head> <title>Titel der Webseite</title> <!-- Kommentare werden nicht angezeigt. --> </head> <body> <div id="header" class="container"> <h1>Überschrift</h1> <p>Inhalt <em>der</em> Webseite</p> </div> </body></html>

Ruby on Rails

Page 29: Gastvortrag Datenbanksysteme: Ruby on Railsdbs/2015/PDF/dbs2015-06-16.pdf5 Migrations • Ruby DSL zur Definition und Manipulation des Datenbankschemas • Datenbankunabhängig (in

29

Embedded Ruby (ERB)

<div id='user-<%= @user.id %>'> <h2> <%= @user.first_name %> <%= @user.last_name %> </h2> <p>Age: <%= @user.age %></p></div>

Ruby on Rails

Einbetten des Rückgabewertes eines Ruby-Ausdruckes

Page 30: Gastvortrag Datenbanksysteme: Ruby on Railsdbs/2015/PDF/dbs2015-06-16.pdf5 Migrations • Ruby DSL zur Definition und Manipulation des Datenbankschemas • Datenbankunabhängig (in

30

ERB und Schleifen<div id="squares"> <% 1.upto(3) do |i| %> <p> The square of <%= i %> is <%= i*i %>.</p> <% end %></div>

Ruby on Rails

<div id="squares"> <p> The square of 1 is 1.</p> <p> The square of 2 is 4.</p> <p> The square of 3 is 9.</p></div>

Ausführung ohne

Einbettung

Page 31: Gastvortrag Datenbanksysteme: Ruby on Railsdbs/2015/PDF/dbs2015-06-16.pdf5 Migrations • Ruby DSL zur Definition und Manipulation des Datenbankschemas • Datenbankunabhängig (in

Controller & Routing

31Ruby on Rails

Page 32: Gastvortrag Datenbanksysteme: Ruby on Railsdbs/2015/PDF/dbs2015-06-16.pdf5 Migrations • Ruby DSL zur Definition und Manipulation des Datenbankschemas • Datenbankunabhängig (in

Ruby on Rails

Controller : UsersController

class UsersController < ApplicationController def show @user = User.find(params[:id]) endend

app/controllers/users_controller.rb

MyRailsApp::Application.routes.draw do get 'users/:id' => "users#show"end

app/config/routes.rb

Page 33: Gastvortrag Datenbanksysteme: Ruby on Railsdbs/2015/PDF/dbs2015-06-16.pdf5 Migrations • Ruby DSL zur Definition und Manipulation des Datenbankschemas • Datenbankunabhängig (in

33

RESTful Controller ActionsHTTP Verb URI Action

GET /users indexPOST /users createGET /users/:id showPUT /users/:id update

DELETE /users/:id destroyGET /users/new newGET /users/:id/edit edit

Page 34: Gastvortrag Datenbanksysteme: Ruby on Railsdbs/2015/PDF/dbs2015-06-16.pdf5 Migrations • Ruby DSL zur Definition und Manipulation des Datenbankschemas • Datenbankunabhängig (in

Ruby on Rails

Demo: Blog

34

Page 35: Gastvortrag Datenbanksysteme: Ruby on Railsdbs/2015/PDF/dbs2015-06-16.pdf5 Migrations • Ruby DSL zur Definition und Manipulation des Datenbankschemas • Datenbankunabhängig (in

35 Ruby on Rails

Anforderungen: Blog

•Ein Blog besteht aus Artikeln

•Artikel gehören zu einer Kategorie

•Ein Artikel kann mit mehreren Schlagworten versehen sein

n

1Category

Article

Tag

n

m