Programowanie w języku Ruby Dr inż. Stanislaw Polak Grupa Systemów Komputerowych https://www.icsr.agh.edu.pl/~polak/ Dr inż. Stanislaw Polak 1 Materialy dla studentów Informatyki wydzialu IET AGH w Krakowie Plan wykladu I Język Ruby Zmienne Struktury kontrolne Typy danych Podprogramy Programowanie funkcyjne Obiektowość Obsluga WWW I Podstawowe pojęcia związane z tworzeniem aplikacji internetowych I Podstawy języka dziedzinowego „Sinatra” I Framework Ruby on Rails Wstęp Przyklad tworzenia aplikacji Kontroler Model Widok Lokalizacja i umiędzynarodowienie Uwierzytelnianie i autoryzacja Dr inż. Stanislaw Polak 2 Notatki Notatki
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Programowanie w języku Ruby
Dr inż. Stanisław Polak
Grupa Systemów Komputerowych
https://www.icsr.agh.edu.pl/~polak/
Dr inż. Stanisław Polak 1
Mat
eriał
ydla
studen
tów
Infor
mat
yki wyd
ziału
IET
AGHw
Krako
wie
Plan wykładu
I Język RubyZmienneStruktury kontrolneTypy danychPodprogramyProgramowanie funkcyjneObiektowośćObsługa WWW
I Podstawowe pojęcia związane z tworzeniemaplikacji internetowych
I Podstawy języka dziedzinowego „Sinatra”I Framework Ruby on Rails
WstępPrzykład tworzenia aplikacjiKontrolerModelWidokLokalizacja i umiędzynarodowienieUwierzytelnianie i autoryzacja
1 # Ten cały wiersz jest komentarzem2 a = "#łańcuch znakowy" #Tu jest komentarz3 a = /#wyrażenie regularne/ #A tu kolejny komentarz4 #5 # Komentarz6 # Ciąg dalszy komentarza7 #
10 <img src="Przyklad.png" alt="Rysunek 1." />11 <p>12 Oto kilka osadzonych HTML. W tym bloku mogę13 dołączać obrazy , użyć <span style="color: green">14 style </span > lub cokolwiek innego , co można zapisa
ć15 w HTML. Procesory RD, które nie wyprowadzają HTML ,16 będą to całkowicie ignorować.17 </p>18 =end19 if a > 220 print "a jest większe od 2\n"21 =begin2223 print "Ala ma kota\n"2425 =end26 b = 227 end28
Dr inż. Stanisław Polak 9
Język Ruby Skrypty
Wypisywanie danych
1 # ’to_s ’ is generally intended to return a human -readable representation of the object ,suitable for end users.
2 #’inspect ’, on the other hand , is intended fordebugging use , and should return arepresentation that is helpful to Rubydevelopers . The default ’inspect ’ method ,inherited from ’Object ’, simply calls ’to_s ’.
Na wyjściu#########################Wprowadź dane:Ala ma kota i psa#########################Wprowadzone dane:Ala ma kota i psa-------------------------"Ala\tma kota i\tpsa\n"#########################
Na wyjściu#########################Wprowadź dane:Ctrl+D#########################Wprowadzone dane:
Na wyjściu#############Wprowadź dane:Ala#############Wprowadzone dane:Ala-------------"Ala\n"#############Wprowadź dane:ma kota i psa#############Wprowadzone dane:ma kota i psa-------------"ma kota i\tpsa\n"#############Wprowadź dane:Ctrl+D
Na wyjściu#############Wprowadź dane:Alama kota i psaCtrl+DAlama kota i psaCtrl+D#############Wprowadzone dane:Alama kota i psaAlama kota i psaCtrl+D-------------"Ala\nma kota i\tpsa\n"["Ala\n", "ma kota i \tpsa\n"]#############
Dr inż. Stanisław Polak 13
Język Ruby Skrypty
Umieszczanie danych w skrypcie
1 puts DATA.read2 END3 puts "Ten kod nie zostanie wykonany"4 Linia 25 Linia 3
Na wyjściu
puts "Ten kod nie zostanie wykonany"Linia 2Linia 3
Dr inż. Stanisław Polak 14
Notatki
Notatki
Język Ruby Skrypty
Umieszczanie danych w skrypciePrzykład zastosowania
1 puts "Kod skryptu"2 END {3 puts "Ten również"4 }5 END {6 puts "Ten kod jest wykonywany tuż po zakończeniu wykonywania
kodu skryptu"7 }8 BEGIN {9 puts "Ten kod jest wykonywany tuż przed rozpoczęciem
wykonywania kodu skryptu"10 }11 BEGIN {12 puts "Ten też"13 }
Na wyjściuTen kod jest wykonywany tuż przed rozpoczęciemwykonywania kodu skryptuTen teżKod skryptuTen kod jest wykonywany tuż po zakończeniu wykonywaniakodu skryptuTen również
1 if FILE == $PROGRAM NAME2 #Zmienna ’__FILE__ ’ ma wartość "skrypt.rb"3 #Zmienna ’$PROGRAM_NAME ’ ma wartość "skrypt.rb"4 puts "Ten skrypt został uruchomiony z linii komend
"5 else6 #Zmienna ’__FILE__ ’ ma wartość "skrypt.rb"7 #Zmienna ’$PROGRAM_NAME ’ ma wartość "irb"8 puts "Ten skrypt został załadowany z poziomu
innego skryptu"9 end
skrypt.rb
1 $ irb2 2.5.0 :001 > load ’./ skrypt.rb’3 Ten skrypt został załadowany z poziomu innego
skryptu4 => true5 2.5.0 :002 > load ’./ skrypt.rb’6 Ten skrypt został załadowany z poziomu innego
skryptu7 => true8 2.5.0 :003 > require ’./ skrypt ’9 Ten skrypt został załadowany z poziomu innego
3 $ rvm install x.x.x # instalacja wersji o numerzex.x.x
InneI JRuby
I Implementacja w JavieI Używa wątków natywnych, brak GILI Używa kompilatora JITI Instalacja
1 $ rvm install jruby
I TruffleRubyI Korzysta z:
I Truffle — platforma do implementacjiwysokowydajnych środowisk językowychkorzystających z Javy oraz wirtualnej maszynyJavy
I GraalVM — wirtualna maszyna Javywyposażona w kompilator JIT o nazwie„Graal”
I Źródła: http://www.oracle.com/technetwork/oracle-labs/program-languages/downloads/
I Informacje o innych implementacjach —http://rvm.io/interpreters/
Dr inż. Stanisław Polak 19
Język Ruby Narzędzia
Ruby w systemie Linux / macOSPorównanie wydajności implementacji
1 def fibonacci(n)2 if n < 23 return n4 end5 return fibonacci(n - 2) + fibonacci(n - 1)6 end7 ## ###############8 def wątki9 i = 100 _000_000
10 2.times.map do11 Thread.new do12 50 _000_000.times { i -= 1 }13 end14 end.each (&: join) #Czekamy aż wszystkie wątki zakończą pracę15 # Znaczenie ’&: nazwa ’ - patrz slajd nr 6116 printf("Końcowa wartość i: %d\n", i)17 end
1 $ rvm use ruby -2.6.12 $ time ruby skrypt.rb3 Czas wykonania: 10.2557804 Końcowa wartość i: 056 real 0m19 ,201s7 user 0m19 ,179s8 sys 0m0 ,013s9 $ time ruby --jit skrypt.rb # Włączona kompilacja JIT
10 Czas wykonania: 3.35290111 Końcowa wartość i: 01213 real 0m9 ,019s14 user 0m17 ,473s15 sys 0m0 ,684s16 # ###########################################17 $ rvm use 9.2.6.0 # Openjdk wersja "11.0.1"18 $ time ruby skrypt.rb19 Czas wykonania: 6.11213620 Końcowa wartość i: 464142852122 real 0m16 ,994s23 user 0m33 ,553s24 sys 0m0 ,313s25 $ time ruby -X-C skrypt.rb # Wyłączona kompilacja JIT26 Czas wykonania: 52.74284027 Końcowa wartość i: 99103692829 real 1m22 ,684s30 user 1m56 ,812s31 sys 0m0 ,340s32 # ###########################################33 $ rvm use truffleruby #GraalVM wersja "1.0.0 - rc13"34 $ time ruby skrypt.rb35 Czas wykonania: 2.04054336 Końcowa wartość i: 383583763738 real 0m4 ,596s39 user 0m7 ,361s40 sys 0m0 ,157s
I Standardowy menedżer pakietów (gemów) Rubiego — działa podobnie jak apt, yum, . . .I Dostępny wraz z Ruby 1.9
Przykłady użycia
1 gem install rails # zainstaluj gem ’Ruby on Rails ’2 gem fetch rails #pobierz gem ’Ruby on Rails ’, ale go nie instaluj3 gem uninstall rails #usuń gem ’Ruby on Rails ’4 gem list --local #wyświetl zainstalowane gemy5 gem list --remote #wyświetl dostępne gemy6 gem search NAPIS --remote # przeszukaj listę dostępnych gemów7 gem rdoc --all #stwórz dokumentacj ę RDoc/RI dla wszystkich zainstalowanych gemów8 gem cleanup #usuń stare wersje zainstalowanych gemów
Dr inż. Stanisław Polak 22
Język Ruby Narzędzia
Tworzenie i generowanie dokumentacjiProgram „rdoc”
1 # The program takes an initial word or phrase from2 # the command line (or in the absence of a3 # parameter from the first line of standard4 # input). In then reads successive words or5 # phrases from standard input and reports whether6 # they are angrams of the first word.7 #8 # Author :: Dave Thomas (mailto:[email protected])9 # Copyright :: Copyright (c) 2002 The Pragmatic Programmers ,
LLC10 # License :: Distributes under the same terms as Ruby1112 # This class holds the letters in the original13 # word or phrase. The is_anagram ? method allows us14 # to test if subsequent words or phrases are15 # anagrams of the original.16 class Anagram1718 # Remember the letters in the initial word19 def initialize(text)20 @initial_letters = letters_of(text)21 end22 # Test to see if a new word contains the same23 # letters as the original24 def is_anagram ?(text)25 @initial_letters == letters_of(text)26 end
27 # Determine the letters in a word or phrase28 #29 # * all letters are converted to lower case30 # * anything not a letter is stripped out31 # * the letters are converted into an array32 # * the array is sorted33 # * the letters are joined back into a string34 def letters_of(text)35 text.downcase.delete(’^a-z’).split(’’).sort.join36 end37 end3839 tester = Anagram.new(ARGV.shift || gets)40 ARGF.each do |text|41 puts "Anagram! " if tester.is_anagram? text42 end
1 $ ri --help2 Usage: ri [options] [names ...]34 Where name can be:56 Class | Module | Module :: Class78 Class:: method | Class#method | Class.method | method9
10 gem_name: | gem_name:README | gem_name:History1112 All class names may be abbreviated to their minimum unambiguous form. If a name13 is ambiguous , all valid options will be listed.1415 A ’.’ matches either class or instance methods , while #method16 matches only instance and :: method matches only class methods.1718 README and other files may be displayed by prefixing them with the gem name19 they’re contained in. If the gem name is followed by a ’:’ all files in the20 gem will be shown. The file name extension may be omitted where it is21 unambiguous.2223 For example:2425 ri Fil26 ri File27 ri File.new28 ri zip29 ri rdoc:README3031 Note that shell quoting or escaping may be required for method names containing32 punctuation:3334 ri ’Array .[]’35 ri compact \!3637 To see the default directories ri will search , run:3839 ri --list -doc -dirs40 ...
1 if warunek [then]2 kod ...3 [elsif warunek [then]4 kod ...]...5 [else6 kod ...]7 end
Składnia
1 if 10 < 20 then2 print "10 jest mniejsze niż 20"3 end
Przykład użycia
Modyfikator „if”
1 kod if warunek
Składnia
1 print "10 jest mniejsze niż 20" if 10 < 20
Przykład użycia
1 liczba = 52 znak = if liczba > 03 ’dodatni ’4 elsif liczba < 05 ’ujemny ’6 else7 ’zero’8 end9 znak
10 => "dodatni"
Dr inż. Stanisław Polak 29
Notatki
Notatki
Język Ruby Struktury kontrolne
Instrukcja warunkowa unless
Wyrażenie „unless”
1 unless warunek [then]2 kod3 [else4 kod ]5 end
Składnia
1 unless str.nil?2 puts str.length3 end4 # W Ruby >= 2.3 powyższe linie można zapisać nastę
pująco:5 # puts str &. length
Przykład użycia
Modyfikator „unless”
1 kod unless warunek
Składnia
1 puts str.length unless str.nil?
Przykład użycia
Dr inż. Stanisław Polak 30
Język Ruby Struktury kontrolne
Instrukcja wyboru
1 ## ####### Forma 1 #########2 case wyrażenie3 [when wyrażenie [, wyrażenie ...] [then]4 kod ]...5 [else6 kod ]7 end89 ## ####### Forma 2 #########
10 case11 [when wyrażenie_logiczne [, wyrażenie_logiczne ...] [then]12 kod ]...13 [else14 kod ]15 end
Składnia
1 liczba = 72 case liczba3 when 1,2,3 # Wykonuje: 1 === liczba || 2 === liczba || 3 ===
liczba4 "mały"5 when 4,5,66 "średni"7 when 7,8,98 "duży"9 else
10 "olbrzymi"11 end12 => "duży"13 ## #########################14 a = 215 case16 when a == 1, a == 217 "a ma wartość jeden lub dwa"18 when a == 319 "a ma wartość trzy"20 else21 "Nie potrafię określić wartości zmiennej a"22 end23 => "a ma wartość jeden lub dwa"24 ## #########################25 case url26 when /http:/27 "protokół HTTP"28 ...29 else30 "nieznany protokół"31 end
Przykład użycia
Dr inż. Stanisław Polak 31
Notatki
Notatki
Język Ruby Struktury kontrolne
Pętle while oraz until1 while warunek [do]2 kod3 end45 begin6 kod7 end while warunek89 kod while warunek
Składnia pętli „while”
1 line=nil2 while line !~ /^$/ do line = gets.chomp end3 ## ######################4 i=15 while i < 36 puts i7 i += 1 #W Ruby nie ma instrukcji : ’++ zmienna ’ / ’zmienna --’, itp.8 j = 29 end
10 puts j #Wypisze: 211 ## ######################12 i=113 begin14 puts i15 i += 116 j = 217 end while i < 3 #Ta konstrukcja nie jest zalecana przez Matz -a18 puts j #Wypisze: 219 ## ######################20 line = gets.chomp while line !~ /^$/
1 until warunek [do]2 kod3 end45 until while warunek67 begin8 kod9 end until warunek
Składnia pętli „until
1 line=nil2 until line =~ /^$/ do line = gets.chomp end3 ## ######################4 i=15 until i >= 3 do6 puts i7 i += 18 j = 29 end
10 puts j #Wypisze: 211 ## ######################12 i=113 begin14 puts i15 i += 116 j = 217 end until i >= 3 #Ta konstrukcja nie jest zalecana przez Matz -a18 puts j #Wypisze: 219 ## ######################20 line = gets.chomp until line =~ /^$/
Dr inż. Stanisław Polak 32
Język Ruby Struktury kontrolne
Instrukcje break, redo oraz next
1 i = 02 while p "Wyrażenie ’while’"3 i += 14 printf "\ti=%d\n", i5 case i6 when 27 puts "\tWykonuję ’next’"8 next9 when 4
10 puts "\tWykonuję ’redo’"11 redo12 when 613 puts "\tWykonuję ’break’"14 break15 end16 puts "\tJestem na końcu ’while’"17 end18 puts ’Koniec ’
Na wyjściu
Wyrażenie ’while’i=1Jestem na końcu ’while’Wyrażenie ’while’i=2Wykonuję ’next’Wyrażenie ’while’i=3Jestem na końcu ’while’Wyrażenie ’while’i=4Wykonuję ’redo’i=5Jestem na końcu ’while’Wyrażenie ’while’i=6Wykonuję ’break’Koniec
Dr inż. Stanisław Polak 33
Mat
eriał
ydla
studen
tów
Infor
mat
yki wyd
ziału
IET
AGHw
Krako
wieNotatki
Notatki
Język Ruby Struktury kontrolne
Pętla loop
1 #Petla nieskończona2 loop do3 puts "Witaj"4 end56 #Petla skończona7 i = 18 loop do9 puts i
10 i += 111 j = 212 break if i > 313 end14 puts j # undefined local variable or method ‘j’
Dr inż. Stanisław Polak 34
Język Ruby Struktury kontrolne
Pętla for oraz metody iteracyjne
1 for i in 1..8 do2 puts i3 end4 # Powyższy kod jest równoważny:5 # (1..8).each{ |i| puts i }6 ## ############7 strs = ["abc\n", "cdae\n", "zzas\n", "aaaa\n"]8 strs.each{ |s| s.chop! }9 p strs
10 ## ############11 5.times { |i| puts i }12 ## ############13 2.upto(4) { |i| puts i }14 ## ############15 4.downto(2) { |i| puts i }16 ## ############17 0.step(10, 2) { |i| puts i }18 ## ############19 0.step(10, 2) do |i|20 puts i21 redo22 end
Na wyjściu
Dr inż. Stanisław Polak 35
Notatki
Notatki
Język Ruby Typy danych Typy podstawowe
Typy liczboweI Integer
1 2 - 3 * 22 =>-43 1.hour + 90. minutes + 1. minute #Dostępne w RoR lub po
1 score = 702 result =3 case score4 when 0..40: "Nie zaliczył (oblał test)"5 when 41..60: "Zaliczył"6 when 61..70: "Zaliczył z wysokim wynikiem"7 when 71..100: "Zaliczył z wyróżnieniem"8 else "Nieprawidłowy wynik testu"9 end
1 ## ##### tworzenie łańcucha #######2 myString = String.new3 => ""4 myString = String.new("This is my string. Get your own string")5 myString = String("This is also my string") #metoda ’String ’
jest metodą modułu "Kernel" - konwersja do typunapisowego
6 myString = "This is also my string"7 myString = ’This is also my string’8 ## ##### wypisanie łańcucha #######9 ’’#{myString} #{1+3}’’ lub %Q&#{ myString} #{1+3}& lub %&#{
myString} #{1+3}& lub %[#{ myString} #{1+3}]10 => "This is also my string 4"11 ’#{myString}’ lub %q&#{ myString}& lub %q(#{ myString})12 => "\#{ myString}"13 ‘ls‘ lub %x&ls& lub %x{ls}14 => Wynik wykonania komendy ’ls’15 ## ##### składnia HereDocs #######16 myText= <<DOC17 118 #{myString}19 DOC20 DOC21 => "1\nThis is also my string\n DOC\n"22 myText= <<-DOC23 124 #{myString}25 DOC26 => "1\nThis is also my string\n"
1 a = ""2 a.nil?3 => false4 a = []5 a.nil?6 => false7 a = 08 a.nil?9 => false
10 a = nil11 a.nil?12 => true13 if 0 and [] and ’’’’14 "True"15 else16 "False"17 end18 => "True"19 if false or nil20 "True"21 else22 "False"23 end # => "False"
Dr inż. Stanisław Polak 53
Notatki
Notatki
Język Ruby Typy danych Typy podstawowe
Porównywanie wartości
1 #Przykład ze strony http :// stackoverflow .com/questions/7156955/ whats -the -difference -between -equal -eql -and
osobnych liniach12 def moja_funkcja((a,b))13 p a: a, b: b14 end15 moja_funkcja ([1 ,2]) #Wypisze: {:a=>1, :b=>2}
Dr inż. Stanisław Polak 55
Mat
eriał
ydla
studen
tów
Infor
mat
yki wyd
ziału
IET
AGHw
Krako
wieNotatki
Notatki
Język Ruby Podprogramy Bloki
Przykłady
1 # definiowanie bloków2 {|x,y,z| x + y + z }3 do |x,y,z|4 x + y + z5 end6 # przekazywanie bloku jako parametru wywołania metody7 a = [1,2,3].reject{|e| e.odd?}8 #przekształcenie w obiekt9 odd = lambda {|e| e.odd?}
10 odd = ->(e){e.odd?} #Składnia dostępna począwszy od wersji 1.9. "()" można pominąć11 even_numbers = [1,2,3]. reject &odd12 odd_number = [1,2,3]. select &odd13 odd.call(3)14 => true15 odd[3] # metoda ’[]’ - alias metody ’call ()’16 => true17 odd.(3) #Składnia dostępna począwszy od wersji 1.918 => true
1 ## ##########2 # Dwuetapowo3 ## ##########4 odd = :odd?.to proc # Zmienna ’odd ’ zawiera obiekt klasy ’Proc ’, reprezentuj ący metodę o nazwie takiej
1 =begin2 funkcja wykorzystuje trzy zmienne:3 ’y’ - dostępną dla użytkownika4 ’x’ - dostępną tylko wewnątrz funkcji ’mnozenie_przez ()’5 ’z’ - dostępną tylko wewnątrz funkcji ’mnozenie_przez ()’6 =end7 ## ##########################################################8 def mnozenie_przez(x)9 z=0
Częściowe zastosowanie funkcji oraz rozwijanie funkcji
1 suma = proc { |x, y, z| (x||0) + (y||0) + (z||0) }2 p suma.call(1, 2, 3) # 63 p suma[1, 2, 3] # 64 ## ############################5 # Częściowe zastosowanie funkcji (ang. partial function
application )6 suma_partial = proc { |x, y| proc { |z| x + y + z } }7 p suma_partial.call(1, 2).call (3) # 68 p suma_partial [1, 2][3] # 69 ## ############################
10 # Rozwijanie "funkcji" (ang. currying)11 suma_curry= proc { |x| proc { |y| proc { |z| x + y + z }
} }12 p suma_curry.call (1).call (2).call (3) # 613 p suma_curry [1][2][3] # 614 p suma.curry[1][2][3] # 615 ## ############################16 f = proc { |x, y, z| [x, y, z] }17 p f[4, 5, 6] # [4, 5, 6]18 p f[4][5 , 6] # nil19 p f[4, 5][6] # nil20 p f[4][5][6] # undefined method ‘[]’ for nil:NilClass (
NoMethodError )2122 g = f.curry23 p g[4, 5, 6] # [4, 5, 6]24 p g[4][5 , 6] # [4, 5, 6]25 p g[4, 5][6] # [4, 5, 6]26 p g[4][5][6] # [4, 5, 6]27 p g[4] # #<Proc :0 x00562b3a477028 >2829 gg = f.curry(2)
30 p gg[4, 5, 6] # [4, 5, 6]31 p gg[4][5 , 6] # [4, 5, 6]32 p gg[4, 5][6] # nil33 p gg [4][5][6] # nil34 p gg[4] # #<Proc :0 x00555ebc5edbc8 >3536 h = g[1] # ’x’ otrzymuje wartość 137 p h[4, 5, 6] # [1, 4, 5]38 p h[4, 5] # [1, 4, 5]39 p h[4][5] # [1, 4, 5]40 p h[4] # #<Proc :0 x000000019404c0 >4142 hh = gg[1] # ’x’ otrzymuje wartość 143 p hh[4, 5, 6] # [1, 4, 5]44 p hh[4, 5] # [1, 4, 5]45 p hh [4][5] # nil46 p hh[4] # [1, 4, nil]4748 i = h[2] # ’y’ otrzymuje wartość 249 p i[4, 5, 6] # [1, 2, 4]50 p i[4, 5] # [1, 2, 4]51 p i[4] # [1, 2, 4]52 p i # #<Proc :0 x00558a3d2a2b38 >5354 ii = hh[2] # ’y’ otrzymuje wartość 255 p ii[4, 5, 6] # wrong number of arguments (given 3,
expected 1..2) ( ArgumentError )56 p ii[4, 5] # nil57 p ii[4] # nil58 p ii # [1, 2, nil]5960 j = i[3] # ’z’ otrzymuje wartość 361 p j # [1, 2, 3]6263 jj = ii[3]64 p jj #nil
Dr inż. Stanisław Polak 67
Język Ruby Programowanie funkcyjne Zasady
Rozwijanie funkcjiPrzykład użycia
1 ## #################################2 # Normal definitions
3 # pattern:∑
f (n) for n ∈ [a . . . b]
4 ## #################################5 sum_ints = lambda do |a,b|6 s = 0 ; a.upto(b){|n| s += n } ; s7 end89 sum_of_squares = lambda do |a,b|
10 s = 0 ; a.upto(b){|n| s += n**2 } ;s11 end1213 sum_of_powers_of_2 = lambda do |a,b|14 s = 0 ; a.upto(b){|n| s += 2**n } ; s15 end1617 puts sum_ints .(1 ,5) #=> 1518 puts sum_of_squares .(1 ,5) #=> 5519 puts sum_of_powers_of_2 .(1 ,5) #=> 6220 ## ##########################################21 # Some refactoring to make some abstraction22 # Passing the sum mechanism itself23 ## ##########################################24 sum = lambda do |f,a,b|25 s = 0 ; a.upto(b){|n| s += f.(n) } ; s26 end
Dostęp do metody klasowej z wnętrza metody instancyjnej
1 class Zwierze2 def metodaInstancyjna3 puts "Jestem metodą instancyjną"4 self.class.metodaKlasowa5 end67 def self.metodaKlasowa8 puts "Jestem metodą klasową"9 end
10 end11 ## ############################12 z = Zwierze.new13 z.metodaKlasowa #Błąd wykonania : undefined method ‘metodaKlasowa ’ ...14 ## ############################15 z.metodaInstancyjna # Wypisze:16 # Jestem metodą instancyjn ą17 # Jestem metodą klasową
Dr inż. Stanisław Polak 81
Notatki
Notatki
Język Ruby Obiektowość Metody
Dziedziczenie
1 class Zwierze #Klasą bazową jest Object2 def initialize3 puts ’Konstruktor Zwierze ’4 end5 end6 ## ###########################7 p Zwierze.superclass #Wypisze: Object8 p Zwierze.superclass.superclass #Wypisze:
BasicObject9 p Zwierze.superclass.superclass.superclass #Wypisze:
10 @@czas211 end12 end13 ## #################14 class Czasomierz15 include Brzeczyk1617 def self.czas118 @czas119 end2021 def self.czas222 @@czas223 end2425 def self.czas2=(czas)26 @@czas2=czas27 end28 end29 ## #################30 p Brzeczyk.czas1 # Wypisze: 131 p Czasomierz.czas1 # Wypisze: nil32 p Brzeczyk.czas2 # Wypisze: 233 p Czasomierz.czas2 # Wypisze: 234 Czasomierz.czas2 = 335 p Brzeczyk.czas2 # Wypisze: 336 p Czasomierz.czas2 # Wypisze: 3
1 module Brzeczyk2 @czas1 = 13 @@czas2 = 245 def self.czas1 # Tutaj ’self ’ oznacza moduł, więc
odbiorcą komunikatu "czas1" będzie tylkomoduł
6 @czas17 end89 def self.czas2
10 @@czas211 end12 end13 ## #################14 class Czasomierz15 include Brzeczyk16 extend Brzeczyk17 end18 ## #################19 p Czasomierz.czas1 # Wyjątek: undefined method ‘
czas1 ’ for Czasomierz :Class20 p Czasomierz.czas2 # Wyjątek: undefined method ‘
czas2 ’ for Czasomierz :Class
Dr inż. Stanisław Polak 88
Język Ruby Obiektowość Inne zagadnienia
Sprawdzanie typu obiektu
1 module Man2 end34 module Woman5 end67 class Person8 include Man9 end
1011 class Player < Person12 include Woman13 end1415 p = Player.new16 p.kind of? Player #true17 p.kind of? Person #true18 p.kind of? Man #true19 p.kind of? Woman #true20 #kind_of? <=> is_a?2122 p.instance of? Player #true23 p.instance of? Person #false24 p.instance of? Man #false25 p.instance of? Woman #false
Dr inż. Stanisław Polak 89
Notatki
Notatki
Język Ruby Obiektowość Inne zagadnienia
Obiekt „main”
1 def funkcja2 puts "Jestem metodą obiektu ’main’"3 end45 class Klasa6 def metoda7 puts "Jestem metodą obiektu ’Klasa’"8 funkcja ()9 end
10 end1112 puts self #Wypisze: main13 puts self.class #Wypisze: Object1415 o=Klasa.new16 o.metoda #Wypisze: Jestem metodą obiektu ’Klasa ’17 # Jestem metodą obiektu ’main ’
10 def -@11 puts "zanegowałeś liczbę"12 end13 end14 liczba = Liczba.new(1)15 puts liczba +416 -liczba
Na wyjściu
5zanegowałeś liczbę
Dr inż. Stanisław Polak 91
Notatki
Notatki
Język Ruby Obiektowość Inne zagadnienia
Kontrola dostępu1 class Test2 public # każda metoda (poza initialize (), która jest prywatna) jest domyślnie publiczna3 def pub_met14 end56 private # metoda prywatna7 def priv_met18 end9
10 protected # wymienione niżej metody są chronione11 def prot_met112 end1314 def prot_met215 end16 end
1 class Test2 def pub_met13 end45 def priv_met16 end78 def prot_met19 end
1011 public :pub_met112 private :priv_met113 protected :prot_met114 end
Dr inż. Stanisław Polak 92
Język Ruby Obiektowość Inne zagadnienia
Kontrola dostępuPrzykład użycia
1 class Foo2 def a3 end45 # Wywołanie ’a()’ z jawnym ’self ’ jako odbiorcą6 def b7 self.a8 end9
1 class HelloWorld2 def call(env)3 req = Rack::Request.new(env)4 odpowiedź = [5 "a="+req.params[’a’][0]+"<br>",6 "a="+req.params[’a’][1]+"<br>",7 "b="+req.params[’b’] # zamiast "req.params[’b ’]"
można użyć "req[’b ’]"8 ]9 return [
10 200,11 {’Content -Type’ => ’text/html;charset=
utf -8’},12 odpowiedź13 ]14 end15 end
helloworld.rb
Dr inż. Stanisław Polak 104
Notatki
Notatki
Język Ruby Obsługa WWW Interfejs Rack
Obsługa formularzy HTMLObiekt Rack::Response
1 class HelloWorld2 def call(env)3 req = Rack:: Request.new(env)4 res = Rack::Response.new5 res.write("a="+req.params[’a’][0]+"<br >") #Dopisuje podany tekst do ciała odpowiedzi6 res.write("a="+req.params[’a’][1]+"<br >")7 res.write("b="+req.params[’b’])8 res[’Content -Type’] = ’text/html;charset=utf -8’ # Ustawienie nagłówka "Content -type"9 res.status = 200 #zbędne , gdyż jest to domyślny kod statusu
10 res.finish #zwróć odpowiedź w postaci ( trzyelementowej ) tablicy11 end12 end
helloworld.rb
Dr inż. Stanisław Polak 105
Język Ruby Obsługa WWW Interfejs Rack
Tworzenie aplikacji pośredniczącej („Middleware”)
1 # Źródło: http :// code.tutsplus.com/articles/exploring -rack --net -329762 class ToUpper3 # Our class will be initialize with another Rack app4 def initialize(app)5 @app = app6 end78 def call(env)9 # First , call ‘@app ‘
10 status , headers , body = @app.call(env)1112 # Iterate through the body , upcasing each chunk13 upcased_body = body.map { |chunk| chunk.upcase }1415 # Pass our new body on through16 [status , headers , upcased_body]17 end18 end19 ## ###############################################20 class Hello21 def self.call(env)22 [ 200, {"Content -Type" => "text/plain"}, ["Hello from Rack!"] ]23 end24 end25 ## ###############################################26 use ToUpper # Tell Rack to use our newly -minted middleware27 run Hello28 # Odpowiednik : app = ToUpper.new(Hello); run app
public"5 use Rack:: ContentType , "text/plain"6 use Rack:: BounceFavicon7 use Rack::Reloader , 08 run HelloWorld.new
config.ru
1 <link rel="stylesheet" href="/css/style.css">
Dokument HTML
1 h1 {color: red}
public/css/style.css
Dr inż. Stanisław Polak 108
Mat
eriał
ydla
studen
tów
Infor
mat
yki wyd
ziału
IET
AGHw
Krako
wieNotatki
Notatki
Podstawowe pojęcia związane z tworzeniem aplikacji internetowych
Framework
I Dostarcza szkieletu do tworzenia aplikacji lub jej wybranych częściI Dostarcza zbioru ogólnych funkcjonalnościI Gotowe komponenty do budowy aplikacji WWWI Ułatwia proces wdrożania nowego pracownikaI Nie jest gotową aplikacją — jest zbiorem kodu i pewnych metod postępowania, dzięki którym
można efektywnie budować aplikacjeI Typowe cechy:
I Odwrócenie sterowaniaI Domyślne zachowanieI RozszerzalnośćI Zamknięta struktura wewnętrzna
I Typowe elementy:I Mechanizm uruchamiania i przetwarzania akcjiI Mechanizm tworzenia logiki biznesowej aplikacjiI Zarządzanie konfiguracjąI Zarządzanie komunikacją z bazą danychI Obsługa formularzyI System szablonówI Obsługa błędówI Mechanizmy bezpieczeństwa, uwierzytelniania i kontroli dostępuI Generatory kodu
Dr inż. Stanisław Polak 109
Podstawowe pojęcia związane z tworzeniem aplikacji internetowych
Wzorzec projektowy MVCŚrodowisko WWW
I MVC (ang. Model-View-Controller) —Model-Widok-Kontroler
I Podstawowe komponenty aplikacji:I Model → logika biznesowaI Widok→ logika prezentacjiI Kontroler → logika sterowania
I Bazuje na klasycznym wzorcu MVCI Zalety:
I StandaryzacjaI NiezależnośćI Łatwość modyfikacjiI Szybkość
I Wada: ZłożonośćI Kiedy stosować?
I Złożone aplikacjeI Potrzeba utrzymywania i dostosowywania do
nowych potrzebI Wyznaczenie obszarów kompetencjiI Wielokrotna używalność
Kontroler Widok
Model
Serwer
Klient
żądanie HTTP odpowiedź HTTP
Dr inż. Stanisław Polak 110
Notatki
Notatki
Podstawowe pojęcia związane z tworzeniem aplikacji internetowych
11 t = ERB.new(zawartosc)12 t.result(binding) # Dokonaj ewaluacji kodu szablonu13 # znajdującego się w zmiennej ’zawartosc
’,14 # a następnie zwróć wygenerowany
dokument15 # HTML16 # Funkcja ’binding ()’ tworzy obiekt klasy ’Binding ’17 # (domknięcie) - obiekty tej klasy enkapsuluj ą kontekst18 # wykonania (wartość zmiennych , ...) w określonym miejscu19 # kodu oraz zachowują ten kontekst do wykorzystania w20 # przyszłości21 end22 end2324 stronaWWW = Strona.new25 stronaWWW.tytul = ’Tytuł strony ’26 stronaWWW.produkty = %w[Produkt1 Produkt2]27 puts stronaWWW.renderuj(’szablon.html.erb’)
skrypt.rb
1 <html>2 <head>3 <title><%= @tytul %></title >4 </head>5 <body>6 <ul>7 <% for produkt in @produkty %>8 <li><%= produkt %></li>9 <% end %>
1 require ’sinatra ’2 require ’sinatra/reloader ’ if development? # Wymaga gema ’sinatra -contrib ’34 get ’/witaj ’ do5 "Witaj Świecie\n"6 end
skrypt.rb
1 $ ruby skrypt.rb2 [2017 -06 -30 18:17:33] INFO WEBrick 1.3.13 [2017 -06 -30 18:17:33] INFO ruby 2.4.1 (2017 -03 -22) [x86_64 -linux]4 == Sinatra (v2.0.0) has taken the stage on 4567 for development with backup from WEBrick5 [2017 -06 -30 18:17:33] INFO WEBrick :: HTTPServer#start: pid =3521 port =4567
Uruchamianie aplikacji
1 $ curl http :// localhost :4567/ witaj2 Witaj Świecie
Wykonywanie żądania
Dr inż. Stanisław Polak 116
Podstawy języka dziedzinowego „Sinatra”
TrasyDefiniowanie
1 get ’/’ do2 .. wyświetl coś ..3 end45 post ’/’ do6 .. utwórz coś ..7 end89 put ’/’ do
1 get ’/witaj ’ do2 "Pierwsza trasa\nhasz ’params ’ zawiera: #{params.inspect }\n"3 end45 get ’/witaj ’ do #Ta trasa nie zostanie (nigdy) dopasowana6 "Druga trasa\nhasz ’params ’ zawiera: #{ params.inspect }\n"7 end89 get ’/witaj/:nazwa’ do
10 "Trzecia trasa\nhasz ’params ’ zawiera: #{params.inspect }\n"11 end
I Serwer aplikacji dla Ruby, Python, Node.js oraz MeteorI Obsługuje żądania HTTP, zarządza procesami oraz zasobami, a także umożliwia administrowanie,
monitorowanie i diagnozowanie problemówI Może działać jako samodzielny serwer aplikacji oraz serwer WWWI Posiada możliwość integracji z serwerami WWW: „Apache” oraz „nginx”
Framework Ruby on Rails Wstęp Narzędzia wiersza poleceń
Program „rails”
1 $ rails2 Usage: rails COMMAND [ARGS]34 The most common rails commands are:5 generate Generate new code (short -cut alias: "g")6 console Start the Rails console (short -cut alias: "c")7 server Start the Rails server (short -cut alias: "s")8 test Run tests (short -cut alias: "t")9 dbconsole Start a console for the database specified in config/database.yml
10 (short -cut alias: "db")11 new Create a new Rails application. "rails new my_app" creates a12 new application called MyApp in "./ my_app"1314 All commands can be run with -h (or --help) for more information.1516 In addition to those commands , there are:17 ...
Dr inż. Stanisław Polak 138
Notatki
Notatki
Framework Ruby on Rails Wstęp Narzędzia wiersza poleceń
Program „rake”
1 $ rake --tasks2 # rails --tasks # Możliwość dostępna w RoR 5.03 ...4 rake db:create # Create the database from DATABASE_URL or config/database.yml
for the current Rails.env (use db:create:all to create all dbs in the config)5 rake db:drop # Drops the database using DATABASE_URL or the current Rails.env
(use db:drop:all to drop all databases )6 rake db:fixtures:load # Load fixtures into the current environment ’s database7 rake db:migrate # Migrate the database (options: VERSION=x, VERBOSE=false , SCOPE
=blog)8 rake db:rollback # Rolls the schema back to the previous version (specify steps w
/ STEP=n)9 rake db:schema:dump # Create a db/schema.rb file that can be portably used against
any DB supported by AR10 rake db:schema:load # Load a schema.rb file into the database11 rake db:seed # Load the seed data from db/seeds.rb12 rake db:setup # Create the database , load the schema , and initialize with the
seed data (use db:reset to also drop the db first)13 rake db:structure:dump # Dump the database structure to db/ structure.sql14 rake routes # Print out all defined routes in match order , with names15 rake test # Runs test:units , test:functionals , test: integration together16 ...
Dr inż. Stanisław Polak 139
Framework Ruby on Rails Wstęp Narzędzia wiersza poleceń
’4 gem ’rails ’, ’4.2.5 ’5 # Use sqlite3 as the database for Active Record6 gem ’sqlite3 ’7 # Use SCSS for stylesheets8 gem ’sass -rails ’, ’~> 5.0’9 # Use Uglifier as compressor for JavaScript assets
1 $ bundle install2 Fetching gem metadata from https :// rubygems.org /...........3 Fetching version metadata from https :// rubygems.org /...4 Fetching dependency metadata from https :// rubygems.org/..5 Resolving dependencies .....6 Using rake 10.4.27 Using i18n 0.7.08 Using json 1.8.39 Using minitest 5.8.3
10 Using thread_safe 0.3.511 Using builder 3.2.212 Using erubis 2.7.013 Using mini_portile2 2.0.014 Using rack 1.6.415 ...16 Using web -console 2.2.117 Using turbolinks 2.5.318 Bundle complete! 12 Gemfile dependencies , 54 gems now
installed.19 Use ‘bundle show [gemname]‘ to see where a bundled gem is
installed.
Instalowanie zależności
Dr inż. Stanisław Polak 140
Notatki
Notatki
Framework Ruby on Rails Wstęp Narzędzia wiersza poleceń
Program „spring”1 $ spring --help2 Version: 1.7.234 Usage: spring COMMAND [ARGS]56 Commands for spring itself:78 binstub Generate spring based binstubs. Use --all to generate a binstub for all known commands. Use --
remove to revert.9 help Print available commands.
10 server Explicitly start a Spring server in the foreground11 status Show current status.12 stop Stop all spring processes for this project.1314 Commands for your application:1516 rails Run a rails command. The following sub commands will use spring: console , runner , generate ,
destroy , test.17 rake Runs the rake command
Dr inż. Stanisław Polak 141
Framework Ruby on Rails Wstęp Testy
TestowanieStruktura katalogów
1 $ ls test2 application_system_test_case.rb fixtures integration models test_helper.rb3 controllers helpers mailers system
Dr inż. Stanisław Polak 144
Mat
eriał
ydla
studen
tów
Infor
mat
yki wyd
ziału
IET
AGHw
Krako
wieNotatki
Notatki
Framework Ruby on Rails Przykład tworzenia aplikacji
Pierwsza aplikacjaZałożenia
I Wyświetlamy dane użytkowników: imię oraz nazwiskoI Dane są umieszczone w kodzie źródłowym kontrolera
Dr inż. Stanisław Polak 145
Framework Ruby on Rails Przykład tworzenia aplikacji
Tworzenie szkieletu aplikacjiOgólna struktura katalogu z kodem aplikacji
1 $ rails new firstApp
firstApp
app
bin
config
config.ru
db
Gemfile
Gemfile.lock
lib
log
package.json
public
Rakefile
README.rdoc
storage
test
tmp
vendor
Dr inż. Stanisław Polak 146
Notatki
Notatki
Framework Ruby on Rails Przykład tworzenia aplikacji
localhost :300021 => Run ‘rails server -h‘ for more startup options22 Puma starting in single mode ...23 * Version 3.4.0 (ruby 2.3.1 - p112), codename: Owl Bowl Brawl24 * Min threads: 5, max threads: 525 * Environment: development26 * Listening on tcp:// localhost :300027 Use Ctrl -C to stop
1 class UsersController < ApplicationController2 USERS = { "abc" => "hasło" }34 before_action :authenticate56 private78 def authenticate9 authenticate_or_request_with_http_digest do |
username|10 USERS[username]11 end12 end13 end
Dr inż. Stanisław Polak 155
Framework Ruby on Rails Kontroler
RoutingCRUD, typy żądań i akcje
1 Users:: Application.routes.draw do2 resources :users3 end
config/routes.rb
ŻądanieHTTP
Ścieżka Akcja Cel użycia
GET /users index wyświetlenie listy wszystkich użytkownikówGET /users/new new zwrócenie formularza HTML do tworzenia użytkow-
nikaPOST /users create utworzenie nowego użytkownikaGET /users/:id show wyświetlenie konkretnego użytkownikaGET /users/:id/edit edit zwrócenie formularza HTML do edycji użytkownikaPATCH /PUT
1 require ’test_helper ’23 class UsersControllerTest < ActionDispatch ::
IntegrationTest4 test ’akcja index przed i po dodaniu rekordu ’ do5 get users_url # akcja ’index ’6 assert response :success7 assert match ’Nowak’, @response.body8 assert no match ’Kowalski ’, @response.body9 ## #################
10 get new_user_url # akcja ’add ’11 assert response :found12 ## #################13 get users_url # akcja ’index ’14 assert response :success15 assert match ’Nowak’, @response.body16 assert match ’Kowalski ’, @response.body17 end18 #Powyższy fragment jest równoważny:19 # def test_akcja_index_przed_i_po_dodaniu_rekordu20 # ...21 # end22 end
test test/controllers/users controller test.rb
Dr inż. Stanisław Polak 162
Notatki
Notatki
Framework Ruby on Rails Model Podstawy
Nadpisywanie konwencji nazewniczych
1 class User < ApplicationRecord2 self.table_name = "uzytkownik" #nazwa tabeli BD3 self.primary_key = "uzytkownik_id" #nazwa kolumny zawierającej klucz główny4 end
Dr inż. Stanisław Polak 163
Framework Ruby on Rails Model Podstawy
Wstawianie danych do BD
1 #Pierwszy sposób - w oparciu o hasz2 user = User.new(imię: "Jan", nazwisko: "Kowalski", pensja: 2000)3 user.save4 #lub5 user = User.create(imię: "Jan", nazwisko: "Kowalski", pensja: 2000)67 #Drugi sposób - w oparciu o blok8 user = User.create do |u|9 u.imię = "Jan"
10 u.nazwisko = "Kowalski"11 u.pensja = 200012 end13 #lub14 user = User.new do |u|15 u.imię = "Jan"16 u.nazwisko = "Kowalski"17 u.pensja = 200018 end19 user.save2021 #Trzeci sposób - poprzez "ręczne" ustawienie atrybutów22 user = User.new23 user.imię = "Jan"24 user.nazwisko = "Kowalski"25 user.pensja = 200026 user.save
Kontroler
Dr inż. Stanisław Polak 164
Notatki
Notatki
Framework Ruby on Rails Model Podstawy
Pobieranie danych z BD
1 #Zwróć kolekcję ze wszystkimi uż ytkownikami (wszystkie rekordy)2 users = User.all34 #Zwróć pierwszego użytkownika (pierwszy rekord)5 user = User.first67 #Odszukaj pierwszego użytkownika o imieniu ’Jan ’ i zwróć go8 jan = User.find_by(imię: ’Jan’)9
10 #Odszukaj wszystkich Janów Kowalskich i posortuj wynik szukania w odwrotnej kolejności według datyutworzenia rekordu
11 params [:user]12 => {"imię"=>"Jan", "nazwisko"=>"Kowalski", "pensja"= >2222}13 params.require(:user)14 => {"imię"=>"Jan", "nazwisko"=>"Kowalski", "pensja"= >2222}15 params.require(: nazwisko)16 ActionController :: ParameterMissing: param is missing or the
value is empty: nazwisko17 params [:user].permit(:imię)18 => {"imię"=>"Jan"}19 params [:user].permit(:imię,:nazwisko)20 => {"imię"=>"Jan", "nazwisko"=>"Kowalski"}21 params [:user].permit(: pesel)22 => {}
Dr inż. Stanisław Polak 168
Notatki
Notatki
Framework Ruby on Rails Model Migracje
Anatomia migracji
1 class CreateUsers < ActiveRecord::Migration[5.1]2 # Wykonanie poniższej metody powoduje komenda: bin/rake db:migrate3 #Zadanie ’db:migrate ’ uruchamia również zadanie ’db:schema:dump ’4 def up5 create table :users do |t|6 #kolumna ’id’ zostanie utworzona automatycznie7 t.string :imię8 t.string :nazwisko9 t.decimal :pensja
10 t.timestamps # utworzenie kolumn: ’created_at ’, ’updated_at ’11 end12 end1314 # Wykonanie poniższej metody powoduje komenda: bin/rake db:rollback15 def down16 drop_table users17 end18 end
db/migrate/YYYYMMDDHHMMSS create users.rb
Dr inż. Stanisław Polak 170
Framework Ruby on Rails Model Migracje
Migracje odwracalne
1 class CreateUsers < ActiveRecord :: Migration [5.1]2 def change3 create_table :users do |t|4 t.string :imię5 t.string :nazwisko6 t.decimal :pensja7 t.timestamps8 end9 end
Informatyki8 #Usuwanie wydziału oraz studentów9 @students = Student.where(faculty_id: @faculty.id)
10 @students.each do |student|11 student.destroy12 end13 @faculty.destroy
Kontroler
Z asocjacjami
1 class Faculty < ApplicationRecord2 has_many :students , dependent: :destroy3 end45 class Student < ApplicationRecord6 belongs_to :faculty7 end
Modele
1 @faculty = Faculty.create(name: "Informatyki")2 #Tworzenie nowego studenta wydziału Informatyki3 @student = @faculty.students.create(firstName: "Jan",lastName:
"Kowalski")4 #Wyświetlenie , dla utworzonego studenta , nazwy wydziału5 puts @student.faculty.name #Wyświetli: Informatyki6 #Usuwanie wydziału oraz studentów7 @faculty.destroy
Kontroler
Dr inż. Stanisław Polak 174
Framework Ruby on Rails Model Asocjacje
Asocjacja „belongs to”
1 class Student < ApplicationRecord2 belongs_to :faculty3 end
Model
1 class CreateStudents < ActiveRecord :: Migration [5.1]2 def change3 create_table :students do |t|4 t.belongs_to :faculty5 t.string : firstName6 t.string : lastName7 end89 create_table :faculties do |t|
10 t.string :name11 end12 end13 end
Migracja
students
Model: Studentbelongs to: faculty
id: integer
faculty id: integer
firstName: string
lastName: string
faculties
Model: Faculty
id: integer
name: string
Dr inż. Stanisław Polak 176
Notatki
Notatki
Framework Ruby on Rails Model Asocjacje
Asocjacja „has one”
1 class Student < ApplicationRecord2 has_one :locker3 end
Model
1 class CreateStudents < ActiveRecord :: Migration [5.1]2 def change3 create_table :students do |t|4 t.string : firstName5 t.string : lastName6 end78 create_table :lockers do |t|9 t.belongs_to :student
10 t.integer :number11 end12 end13 end
Migracja
students
Model: Studenthas one: locker
id: integer
firstName: string
lastName: string
lockers
Model: Locker
id: integer
student id: integer
number: integer
Dr inż. Stanisław Polak 177
Framework Ruby on Rails Model Asocjacje
Asocjacja „has many”
1 class Faculty < ApplicationRecord2 has_many :students3 end
Model
1 class CreateFaculties < ActiveRecord :: Migration [5.1]2 def change3 create_table :faculties do |t|4 t.string :name5 end67 create_table :students do |t|8 t.belongs_to :faculty9 t.string :firstName
10 t.string :lastName11 end12 end13 end
Migracja
faculties
Model: Facultyhas many: students
id: integer
name: string
students
Model: Student
id: integer
faculty id: integer
firstName: string
lastName: string
Dr inż. Stanisław Polak 178
Mat
eriał
ydla
studen
tów
Infor
mat
yki wyd
ziału
IET
AGHw
Krako
wieNotatki
Notatki
Framework Ruby on Rails Model Asocjacje
Asocjacja „has many :through”
1 class Student < ApplicationRecord2 has_many :classes3 has_many :teachers , through: classes4 end56 class Class < ApplicationRecord7 belongs_to :student8 belongs_to :teacher9 end
1011 class Teacher < ApplicationRecord12 has_many :classes13 has_many :students , through: classes14 end
Model
1 class CreateClasses < ActiveRecord :: Migration [5.1]2 def change3 create_table :students do |t|4 t.string :firstName5 t.string :lastName6 end78 create_table :teachers do |t|9 t.string :name
10 end1112 create_table :classes do |t|13 t.belongs_to :student14 t.belongs_to :teacher15 t.datetime :term16 end17 end18 end
Migracja
students
Model: Studenthas many :classeshas many :teachers,:through=> :classes
id: integer
firstName: string
lastName: string
classes
Model: Classbelongs to :studentbelongs to :teacher
id: integer
student id: integer
teacher id: integer
term: datetime
teachers
Model: Teacherhas many :classeshas many :students,:through=> :classes
id: integer
name: string
Dr inż. Stanisław Polak 179
Framework Ruby on Rails Model Asocjacje
Asocjacja „has one :through”
1 class Student < ApplicationRecord2 has_one :account3 has_one :account_history , through: :account4 end56 class Account < ApplicationRecord7 belongs_to :student8 has_one :account_history9 end
1011 class AccountHistory < ApplicationRecord12 belongs_to :account13 end
Model
1 class CreateAccountHistories < ActiveRecord :: Migration [5.1]2 def change3 create_table :students do |t|4 t.string :firstName5 t.string :lastName6 end78 create_table :accounts do |t|9 t.belongs_to :student
10 t.string :account_number11 end1213 create_table :account_histories do |t|14 t.belongs_to :account15 t.integer :return_book_punctuality_rating16 end17 end18 end
Migracja
students
Model: Studenthas one :accounthas one :account history, :through=> :account
id: integer
firstName: string
lastName: string
accounts
Model: Accountbelongs to :studenthas one :account history
id: integer
student id: integer
account number: string
account histories
Model: AccountHistorybelongs to :account
id: integer
account id: integer
return book punctuality rating: integer
Dr inż. Stanisław Polak 180
Notatki
Notatki
Framework Ruby on Rails Model Asocjacje
Asocjacja „has and belongs to many”
1 class Student < ApplicationRecord2 has_and_belongs_to_many :teachers3 end45 class Teacher < ApplicationRecord6 has_and_belongs_to_many :students7 end
Model
1 class CreateStudentsAndTeachers < ActiveRecord :: Migration [5.1]2 def change3 create_table :students do |t|4 t.string :firstName5 t.string :lastName6 end78 create_table :teachers do |t|9 t.string :name
10 end1112 create_table :students_teachers , id: false do |t| #id:
false - tabela nie będzie zawierała klucza głównego13 t.belongs_to :student14 t.belongs_to :teacher15 end16 end17 end
Migracja
students
Model: Studenthas and belongs to many :teachers
id: integer
firstName: string
lastName: string
students teachers
student id: integer
teacher id: integer
teachers
Model: Teacherhas and belongs to many :students
id: integer
name: string
Dr inż. Stanisław Polak 181
Framework Ruby on Rails Model Asocjacje
Asocjacja polimorficzna
1 class Picture < ApplicationRecord2 belongs_to :imageable , polymorphic: true3 end45 class Student < ApplicationRecord6 has_many :pictures , as: :imageable7 end89 class Teacher < ApplicationRecord
10 has_many :pictures , as: :imageable11 end
Model
1 class CreatePictures < ActiveRecord :: Migration [5.1]2 def change3 create_table :pictures do |t|4 t.string :name5 t.references :imageable , polymorphic: true6 end7 end8 end
Migracja
students
Model: Studenthas many :pictures, :as => :imageable
id: integer
firstName: string
lastName: string
pictures
Model: Picturebelongs to :imageable,polymorphic: true
id: integer
name: string
imageable id: integer
imageable type: string
teachers
Model: Teacherhas many :pictures, :as => :imageable
id: integer
name: string
Dr inż. Stanisław Polak 182
Notatki
Notatki
Framework Ruby on Rails Model Przykład tworzenia aplikacji
Czynności wstępne
1 $ rails new library --skip -action -cable --skip -active -storage --skip -action -mailer2 $ cd library3 $ vi config/routes.rb4 $ bin/rake routes5 Prefix Verb URI Pattern Controller#Action6 books GET /books (.: format) books#index7 POST /books (.: format) books#create8 new_book GET /books/new(.: format) books#new9 edit_book GET /books /:id/edit (.: format) books#edit
10 book GET /books/:id(.: format) books#show11 PATCH /books /:id(.: format) books#update12 PUT /books/:id(.: format) books#update13 DELETE /books/:id(.: format) books#destroy14 subjects GET /subjects (.: format) subjects#index15 POST /subjects (.: format) subjects#create16 new_subject GET /subjects/new (.: format) subjects#new17 edit_subject GET /subjects /:id/edit (.: format) subjects#edit18 subject GET /subjects /:id(.: format) subjects#show19 PATCH /subjects /:id(.: format) subjects#update20 PUT /subjects /:id(.: format) subjects#update21 DELETE /subjects /:id(.: format) subjects#destroy
1 Rails.application.routes.draw do2 # maps HTTP verbs to controller actions automatically3 resources :books4 resources :subjects5 end
config/routes.rb
Dr inż. Stanisław Polak 184
Framework Ruby on Rails Model Przykład tworzenia aplikacji
Konfigurowanie bazy danych
1 $ vi library/config/database.yml
1 # SQLite version 3.x2 # gem install sqlite33 #4 # Ensure the SQLite 3 gem is defined in your Gemfile5 # gem ’sqlite3 ’6 #7 default: &default8 adapter: sqlite39 pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
10 timeout: 50001112 development:13 <<: *default14 database: db/development.sqlite31516 # Warning: The database defined as "test" will be erased and17 # re - generated from your development database when you run "rake ".18 # Do not set this db to the same as development or production .19 test:20 <<: *default21 database: db/test.sqlite32223 production:24 <<: *default25 database: db/production.sqlite3
config/database.yml
Dr inż. Stanisław Polak 185
Notatki
Notatki
Framework Ruby on Rails Model Przykład tworzenia aplikacji
Framework Ruby on Rails Model Przykład tworzenia aplikacji
Wyświetlanie listy książek
1 class BooksController < ApplicationController2 def index3 @books = Book.all4 @subjects = Subject.all5 end6 ...7 end
app/controllers/books controller.rb
1 <% if @books.blank? %>2 <p>There are not any books currently in the system.</p>3 <% else %>4 <ul id="subjects">5 <% @subjects.each do |subject| %>6 <li><%= link_to subject.name , subject_path(subject) %></li>7 <% end %>8 </ul>9 <p>These are the current books in our system </p>
10 <ul id="books">11 <% @books.each do |book| %>12 <li>13 <%= link_to book.title , book_path(book) %> <!-- np. /books /3 -->14 <%= link_to ’Edit ’, edit_book_path(book) %> <!-- np. /books /3/ edit -->15 <%= link_to ’Destroy ’, book_path(book), method: :delete , data: { confirm: ’Are you sure?’ } %>16 <% end %>17 </ul>18 <% end %>19 <p><%= link_to "Add new Book", new_book_path %></p> <!-- /books/new -->
app/views/books/index.html.erb
Dr inż. Stanisław Polak 189
Mat
eriał
ydla
studen
tów
Infor
mat
yki wyd
ziału
IET
AGHw
Krako
wieNotatki
Notatki
Framework Ruby on Rails Model Przykład tworzenia aplikacji
Dodawanie nowej książki
1 class BooksController < ApplicationController2 ...3 def new4 end56 def create7 params.permit! #Wymagane w RoR 4.08 @book = Book.new(params [:book])9 if @book.save
10 redirect_to books_path # przekierowanie do akcji books#index
Framework Ruby on Rails Model Przykład tworzenia aplikacji
Kasowanie książki
1 class BooksController < ApplicationController2 ...3 def destroy4 book = Book.find(params [:id])5 book.destroy6 redirect_to books_path7 end8 ...
app/controllers/books controller.rb
Dr inż. Stanisław Polak 193
Notatki
Notatki
Framework Ruby on Rails Model Walidacja
Wyświetlanie błędów walidacji w widoku
1 <%= form_with scope: :book , url: books_path do |f| %>2 <% if @book.errors.any? %>3 <div id="error_explanation">4 <h2 ><%= pluralize(@book.errors.count , "error") %> prohibited this book from being saved:</h2 >5 <ul>6 <% @book.errors.full_messages.each do |msg| %>7 <li ><%= msg %></li >8 <% end %>9 </ul >
10 </div >11 <% end %>12 ...13 <!-- Pola formularza -->14 <% end %>
app/views/users/new.html.erb
Dr inż. Stanisław Polak 196
Framework Ruby on Rails Model Walidacja
Pomocnicy walidacji
1 class Book < ApplicationRecord2 belongs_to :subject3 validates :title , presence:true4 validates :price , numericality: true5 end
Dr inż. Stanisław Polak 197
Notatki
Notatki
Framework Ruby on Rails Model Testy jednostkowe
Osprzęt (ang. Fixture)
I Sposób organizowania danych testowychI Podstawowe dane, którymi zapełniana jest baza danychI Jest niezależny od silnika bazy danychI Zapisujemy w formacie YAMLI Jeden model — jeden plik z osprzętem
1 #komentarz2 one:3 title: O obrocie sfer niebieskich4 description: Biały kruk5 subject: physics6 two:7 title: Lenin , działa wybrane8 price: 109 subject: physics
test/fixtures/books.yml
1 physics:2 name: Physics
test/fixtures/subjects.yml
Dr inż. Stanisław Polak 198
Framework Ruby on Rails Model Testy jednostkowe
Testy jednostkowe modeli
1 require ’test_helper ’23 class BookTest < ActiveSupport :: TestCase4 test "not_valid" do5 book = books(:one)6 assert book.valid?, "Błąd walidacji"?7 end8 #Powyższy fragment jest równoważny:9 # def test_not_valid
10 # ...11 # end1213 test "valid" do14 book = books(:two)15 assert book.valid?, "Błąd walidacji"?16 end17 end
test/models/book test.rb”
Dr inż. Stanisław Polak 199
Notatki
Notatki
Framework Ruby on Rails Model Testy jednostkowe
Przygotowywanie aplikacji do testowania i uruchamianie testów
1 bin/rails generate integration_test books_flows2 vim test/integration/books_flows_test.rb
1 require ’test_helper ’23 class BooksFlowsTest < ActionDispatch::IntegrationTest4 test "browse site" do5 get "/books"6 assert_response :success # Czy status odpowiedzi to 20078 get "/books/new"9 assert_response :success
Framework Ruby on Rails Lokalizacja i umiędzynarodowienie
Umiędzynarodowienie i lokalizacja
Umiędzynarodowienie polega na dodaniu do aplikacji możliwości wpisywania, przetwarzania iwyświetlania (generowania) tekstu w różnych językach.
Lokalizacja jest procesem polegającym na dostosowaniu aplikacji do określonych ustawieńregionalnych (przetłumaczenie tekstów na odpowiedni język, dostosowanie formatuwaluty, formatu liczb, formatu dat, itp.).
Dr inż. Stanisław Polak 211
Mat
eriał
ydla
studen
tów
Infor
mat
yki wyd
ziału
IET
AGHw
Krako
wieNotatki
Notatki
Framework Ruby on Rails Lokalizacja i umiędzynarodowienie
Gem I18n
Co oferujeI Wsparcie dla języka angielskiego i języków do niego podobnychI Ułatwienie dostosowania i rozbudowywania aplikacji dla innych języków
Ogólna struktura gem-aI Publiczne API frameworku I18n — moduł Ruby z publicznymi metodami i definicjami,
określającymi sposób działania bibliotekiI Domyślny back-end (celowo nazywany prostym back-endem) , implementujący powyższe metody
Dr inż. Stanisław Polak 212
Framework Ruby on Rails Lokalizacja i umiędzynarodowienie
Konfiguracja modułu I18n
1 en:2 title: "Library Info System"3 info: "Library powered by Ruby on Rails %{ version
}"
config/locales/en.yml
1 pl:2 title: "Biblioteczny System Informacyjny"3 info: "Biblioteka w oparciu o Ruby on Rails %{
version}"
config/locales/pl.yml
1 ...2 # The default locale is :en and all translations from config/locales /*.rb ,yml are auto loaded.3 # config.i18n.load_path += Dir[Rails.root.join(’my ’, ’locales ’, ’*.{rb ,yml}’).to_s]4 # config.i18n. default_locale = :de5 ...
config/application.rb
1 $ vi Gemfile2 $ bundle install
Instalowanie gem-a ’rails-18n’
1 ...2 gem ’rails -i18n’
Gemfile
Dr inż. Stanisław Polak 213
Notatki
Notatki
Framework Ruby on Rails Lokalizacja i umiędzynarodowienie
1 <% if @books.blank? %>2 <p>Obecnie w systemie nie ma żadnych książek </p>3 <% else %>4 <ul id="subjects">5 <% @subjects.each do |subject| %>6 <li ><%= link_to subject.name , subject_path(subject) %></li>7 <% end %>8 </ul >9 <p>Oto książki znajdujące się w naszym systemie </p>
Framework Ruby on Rails Uwierzytelnianie i autoryzacja Gem „Device”
Gem „Devise”Ogólna charakterystyka
I Oparty na Rack-uI Kompletne rozwiązanie MVC oparte na silnikach RailsI Jest oparty na koncepcji modułowej: „Używasz tylko tego, czego naprawdę potrzebujesz”
Moduły
1. Database Authenticatable
2. Omniauthable
3. Confirmable
4. Recoverable
5. Registerable
6. Rememberable
7. Trackable
8. Timeoutable
9. Validatable
10. Lockable
Dr inż. Stanisław Polak 218
Framework Ruby on Rails Uwierzytelnianie i autoryzacja Gem „Device”
Instalowanie gema
1 $ vi Gemfile2 $ bundle install
1 ...2 gem ’devise ’3 gem ’devise -i18n’
Gemfile
Dr inż. Stanisław Polak 219
Notatki
Notatki
Framework Ruby on Rails Uwierzytelnianie i autoryzacja Gem „Device”
Inicjalizacja
1 $ bin/rails generate devise:install2 create config/initializers/devise.rb3 create config/locales/devise.en.yml4 =========================================56 Some setup you must do manually if you haven ’t yet:7 ...89 $ vi config/initializers/devise.rb
1 # Use this hook to configure devise mailer , warden hooks andso forth.
2 # Many of these configuration options can be set straight inyour model.
3 Devise.setup do |config|4 # The secret key used by Devise. Devise uses this key to
generate5 # random tokens. Changing this key will render invalid all
existing6 # confirmation , reset password and unlock tokens in the
Framework Ruby on Rails Uwierzytelnianie i autoryzacja Gem „Device”
Wymuszanie uwierzytelniania
1 class ApplicationController < ActionController ::Base2 protect_from_forgery with: :exception3 before_action :set_locale ,:authenticate user! #Tekst występujący po znaku ’_’ jest nazwą modelu4 ...5 end
app/controllers/application controller.rb
Dr inż. Stanisław Polak 224
Framework Ruby on Rails Uwierzytelnianie i autoryzacja Gem „Device”
Framework Ruby on Rails Uwierzytelnianie i autoryzacja Gem „Device”
Rejestracja i logowanie
Dr inż. Stanisław Polak 226
Framework Ruby on Rails Gem „Pundit”
Gem „Pundit”Ogólna charakterystyka
I Umożliwia stworzenie prostego, solidnego i skalowalnego systemu autoryzacjiI Autoryzacja w oparciu o klasy politykI Pozwala określić zakres widoczności rekordów BD dla użytkownikówI Wspomaga obsługę „silnych” parametrów
Dr inż. Stanisław Polak 227
Notatki
Notatki
Framework Ruby on Rails Gem „Pundit”
Instalowanie gema
1 $ vi Gemfile2 $ bundle install
1 ...2 gem ’pundit ’
Gemfile
Dr inż. Stanisław Polak 228
Framework Ruby on Rails Gem „Pundit”
Dodawanie „Pundit” do kontrolera
1 class ApplicationController < ActionController ::Base2 include Pundit3 ...4 end
app/controllers/application controller.rb
Dr inż. Stanisław Polak 229
Notatki
Notatki
Framework Ruby on Rails Gem „Pundit”
Przykładowa polityka dostępu
Zwykły użytkownikI Może wyświetlać listę książekI Może wyświetlać informacje o pojedynczej
książceI Może usuwać książki z Chemii
AdministratorI Może wyświetlać listę książekI Może wyświetlać informacje o pojedynczej
książceI Może dodawać nowe książkiI Może usuwać książkiI Może edytować książki