Git Product home page Git Product logo

ror4beginners2018's Introduction

Ruby on Rails 4 beginners

alt text

Plan zajęć

alt text

Przydatne materiały

  • Dokumentacja Ruby(Gdy przeglądacie daną stronę dokumentacji, zwracajcie uwagę dla której wersji rubiego dana strona jest)
  • Styleguide(Gem Rubocop potrafi automatycznie pilnować go za was)

Przygotowanie do zajęć

instalacja ruby

Linux/Unix/Mac os

Jeśli masz system z rodziny Unix sprawa jest dosyć prosta - wystarczy wywołać w terminalu komendę irb, aby wyświetlić znak zachęty interpretera rubiego.

➜  ~ irb
2.5.1 :001 > 

Jeśli jednak tak się nie stało, a komenda which ruby nic nie zwraca, postępuj zgodnie z instukcjami w linku:

Debian lub Ubuntu: https://www.ruby-lang.org/pl/documentation/installation/#apt

OS X: https://www.ruby-lang.org/pl/documentation/installation/#homebrew

Arch Linux: https://www.ruby-lang.org/pl/documentation/installation/#pacman

Gentoo: https://www.ruby-lang.org/pl/documentation/installation/#gentoo

CentOS, Fedora lub RHEL: https://www.ruby-lang.org/pl/documentation/installation/#yum

Windows

alt text

Z Windowsem sprawa jest nieco bardziej skomplikowana. Jeśli nie instalowałeś rubiego samodzielnie - prawdopodobnie go nie masz. Należy w takim razie wejść na https://rubyinstaller.org/downloads/ i ściągnąć najnowszą wersję Ruby+Devkit 2.5.X

Windows i Ruby on Rails nie są najlepszymi kumplami, dlatego mając system Microsoftu warto zainstalować sobie maszynę wirtualną z dowolnym systemem Linux i pracować na niej - unikniesz w ten sposób bólu głowy.

Wybór edytora tekstu

Programowanie w Rubym nie wymaga żadnych specjalistycznych narzędzi - wystarczy korzystać z edytora tekstu. Na zajęciach możesz korzystać z dowolnego edytora. Jeżeli nie wiesz co wybrać, polecamy VS Code https://code.visualstudio.com/.

Przesyłanie zadań domowych

Aby przesłać nam rozwiązane zadania należy zrobić:

  • fork projektu (prawy górny róg githuba)
  • pobrać go do swojego lokalnego środowiska git clone ...
  • stworzyć nowy branch z nazwą zadania git checkout -b 'zad1' && git push --set-upstream origin zad1
  • rozwiązać zadanie i wrzucić do swojego forka git commit -m '' && git push
  • stworzyć pull request do daftcode/ror4beginners2018

Pytania / kontakt

Jak macie jakieś pytania, albo coś nie działa, dajcie znać na [email protected] lub napiszcie issue.

ror4beginners2018's People

Contributors

tengoot avatar ahawrylak avatar resool avatar kruczekp avatar h4nky avatar

Stargazers

Kinga avatar  avatar agnikka avatar  avatar  avatar Raihan Nismara avatar Alicja W avatar Łukasz Paweł Bieliński avatar  avatar norbert avatar

Watchers

James Cloos avatar  avatar  avatar  avatar  avatar Michał Olejniczak avatar  avatar Mariia Buravkova avatar Łukasz Paweł Bieliński avatar Maciej Janusz Krajsman avatar  avatar

ror4beginners2018's Issues

Udostępnianie rozwiązań?

Czy jest szansa na udostępnianie rozwiązań zadań do przeanalizowania na spokojnie bez rozbieganych oczek? :)

instalacja rails pod windows 10

Mam problem z instalacją ( a właściwie uruchomieniem ) railsów.
Ogólnie dotyczy to problemu z sqlite3.
Przeczytałem ze dwa wątki na stacku, znalazłem coś co miało być pożądanym plikiem sqlite3.h jednak nadal coś jest nie tak, czy ktoś może miał podobny problem?

Zad3 bestiary_controller directory wrong name

Issue: Domyślna ścieżka renderu widoku dla bestiary_controller jest błędna.

Z tego co widzę to przy generowaniu kontrolera za pomocą cli
rails g controller bestiary
Otrzymamy w app/controllers/bestiary_controller.rb i to się zgadza.
Aczkolwiek z nieznanego mi powodu
app/views również posiada bestiary_controller, gdzie powinno być samo bestiary (przynajmniej tak domyślnie jest tworzone przez cli: app/views/bestiary). Konsekwencją błędnej ścieżki jest niewyrenderowany widok.

Solution:
Jedyną poprawką do wykonania, aby domyślnie wszystko się spieło to poprawa nazwy folderu we views z bestiary_controller na samo bestiary.

screenshot 2018-11-14 at 23 24 15

Zły artist input przy wysłaniu formularza z błędem walidacji

Co prawda jest to błąd nieprzeszkadzający w rozwiązaniu zadania domowego, ale jednak błąd.

Po wysłaniu formularza dla nowego utworu (po zdefiniowaniu walidacji) input dla artysty zmienia się z select na input typu number.

Dzieje się tak, dlatego że zmienna @artists po render 'new' ma wartość nil, ponieważ jest przekazana callbackiem before_action, a przy błędzie w formularzu akcja new nie jest wywoływana ponownie. Tak samo dzieje się dla edit.

Fix:

Ponowne wywołanie metody set_artists_collection przed akcjami create/update naprawia błąd, ale nie wiem czy to najlepsze wyjście z sytuacji.

  before_action :set_artists_collection, only: %i[new create edit update]

dziedziczenie i metody

Chciałbym zwrócić uwagę na problem podnoszenia poziomu postaci. Odpowiem w tym issue na pytanie gdzie powinna być zlokalizowania jego logika.

Większość z was rozwiązała problem następująco:

class Character; end

class Monster < Character; end

class Warrior < Character
  def level_up(param)
     do_sth(param)
  end
end

class BattleArena
  def battle!
     ...
     winner.level_up if winner.is_a?(Warior)
  end
end

Jest okej, jednak logika jest w tej chwili mocno podzielona między dwie klasy. Co jeśli dojdą później inne klasy mogące podnosić poziom? Będziemy musieli robić coś takiego [Klass1, Klass2, Klass3].any?{ |klass| winner.is_a?(Warrior) }. Część z was użyła też winner.respond_to?(level_up) co pozwoliłoby uniknąć takiej sytuacji.
Jednak tak naprawdę klasę BattleArena nie powinno interesować czy ma doczynienia z ghoulem czy paladynem - ona pozwala zorganizować spotkanie dwóch postaci i ustalić wynik - nic więcej. To czy wygrany wyciągnie z niej lekcje i zwiększy mu się poziom - to już jego problem.

Propozycja z mojej strony:

  • definiujemy podstawowe zachowanie level_up w klasie Character
  • nadpisujemy to zachowanie w klasie Monster lub Warrior (w tym przypadku Warrior brzmi sensowniej, ale z reguły takie wybory zależą od danego kontekstu, oceny sytuacji, w której domyślne zachowanie wykona się przez przypadek czy stosowania metody DRY)
class Character
  def level_up(param); end # do nothing - default behaviour
end

class Monster < Character; end

class Warrior < Character
  def level_up(param)
     do_sth(param)
  end
end

class BattleArena
  def battle!
     ...
     winner.level_up(param)
  end
end

FootballPlayerManager jest niewidoczny

Przy podaniu w konsoli komendy
player_manager = FootballPlayerManager.new(player)
wyskakuje mi błąd : Unable to autoload constant FootballPlayerManager, expected E:/Rails/Exercise/App/services/football_player_manager.rb to define it.
Póki co w pliku football_player_manager.rb jest jego oryginalna zawartość a ścieżki są właściwe (nawet jeżeli teraz zrobiłem literówki przepisując je). Ścieżki są takie jakie są, gdyż pliki u mnie są tak właśnie zlokalizowane. Czy to jest jakaś kwestia związana z traktowaniem plików z katalogu services – a jeżeli tak, to gdzie o tym przeczytać, czy chodzi o coś innego ( a jeżeli tak, gdzie szukać wskazówek)? Zakładam że plik nawet w postaci pierwotnej powinien tworzyć instancję swojej klasy. 'player' jest zdefiniowany i ma wartości.

Modele w kontrolerach

Dlaczego w TracksController przy próbie wywołania

screenshot 2018-12-05 at 15 48 01

obiekt @playlist_tracks jest typu nil w widoku Tracks? W routes.rb nie dodawałem żadnej ścieżki, czy problem leży w tym, że w danym kontrolerze nie możemy korzystać z innych modelów?

Problem z tworzeniem instancji modelu

Mam mały problem, zdefiniowałem sobie cały model, stworzyłem tabelę w bazie danych, ale za każdym razem gdy chcę utworzyć instancję modelu, rails wywala mi to:

screenshot 2018-11-28 at 00 09 00

Tak jakby gubi wszystkie wartości atrybutów.

Zadanie 3 prośba o bliższą interpretacje polecenia

Właściwie miałbym pytanie o wyprowadzenie danych 'na widok'. O ile wszystko dobrze zrozumiałem nie należy łączyć logiki i prezencji. W takim razie nie bardzo rozumiem jak wyświetlić wielokrotnie te dane potworów między parą odpowiednich tagów. Nie ma problemu z wygenerowaniem tabeli czy czegokolwiek, ale ta tabela będzie między jedną parą tagów HTML w całości. Chyba że rozwiązaniem OK jest wypisaniem w widoku 20 czy tam ilu powtarzalnych sekwencji ale to nie jest DRY. Na pewno przeoczyłem coś oczywistego, ktoś mnie naprowadzi?

attr_reader, attr_writer i attr_accessor

attr_reader :foo tworzy metodę getter w klasie:

def foo
  @foo
end

attr_writer :foo tworzy metodę setter w klasie:

def foo=(value)
  @foo = value
end

attr_accessor :foo tworzy metody setter i getter w klasie:

def foo
  @foo
end

def foo=(value)
  @foo = value
end

Kiedy w klasie mamy gettera możemy odczytywać zmienną instancji @foo przez metodę foo, czyli nie musimy pamiętać o @ wewnątrz klasy i możemy odczytywać ją z innego obiektu:

class Test
  attr_reader :foo
  
  def initialize(number)
    @foo = number * 2 
  end

  def result
    "result = #{foo}"  # foo bez @
  end
end

test = Test.new(10)
test.result #=> "result = 20"
test.foo #=> 20
test.foo = 50 #=> NoMethodError (undefined method `foo=' for <Test:...>)

Ostatnia linijka zwraca błąd ponieważ nie użyliśmyattr_writer :foo lub attr_accessor :foo do zdefiniowania settera.

Kiedy warto korzystać z getterów / setterów?

Poniżej zamieszczono przykłady z zadania nr 2, jednak użyłem ich tylko dlatego, aby przybliżyć problem. Nie stanowią one "poprawnego sposobu" wykonania zadania.
Do parametrów initializerów dodałem suffix _param, aby odróżnić parametry od definiowanych atrybutów.

  1. Jeśli chcemy odczytywać level postaci poza klasą Warrior / Monster musimy ustawić attr_reader :level jako metoda publiczna - czyli nie pod keywordem protected czy private. Pamiętaj, że możesz po przecinku dodać więcej atrybutów
class Monster < Character
  attr_reader :level, :name

  def initialize(name_param:, level_param:)
    @name = name_param
    @level = level_param
  end
end

andariel = Monster.new(name_param: 'Andariel', level_param: 5)
andariel.name # => Andariel
andariel.level # => 5
  1. Jeśli chcemy zmienić wartość levelu postaci poza jego klasą, np w klasie BattleArena, powinniśmy zdefiniować attr_writer :level(przypominajka: attr_writer + attr_reader = attr_accessor ) także jako metoda publiczna
class Warrior < Character
  attr_reader :name
  attr_accessor :level

  def initialize(name_param:, level_param:)
    @name = name_param
    @level = level_param
  end
end

barbarian = Warrior.new(name_param: 'Barbarian', level_param: 5)
barbarian.name # => Barbarian
barbarian.level = 10
barbarian.level # => 10
  1. Jeśli w klasie BattleArena mamy dwie zmienne instancji, np first_character i second_character i nigdzie poza klasą ich nie używamy możemy użyć attr_reader :first_character, :second_character w sekcji prywatnej. Dlaczego nie używać po prostu @first_character i @second_character do odczytu zmiennych instancji? Zauważ, że kiedy zrobisz literówkę i wpiszesz first_chararter ruby zareaguję odrazu krzycząc - undefined method first_chararter, kiedy jednak wpiszesz @first_chararter, ruby zwróci nil i przy niepoprawnie działającej aplikacji może nie zwrócić błędu wcale. 😨
class BattleArena
  def initialize(first_character_param:, second_character_param:)
    @first_character = first_character_param
    @second_character = second_character_param
  end

  def battle!
    first_character # access to first character
    second_character # access to second character
  end

  private

  attr_reader :first_character, :second_character
end

battle = BattleArena.new(first_character_param: character1, second_character_param: character2)
battle.first_character # => NoMethodError (private method `first_character' called for #<BattleArena:...>)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.