Jakiś czas temu deliberowaliśmy ( :] ) na forum jak najszybciej i najbardziej elegancko rozwiązać wywołanie #next na każdym znaku Stringa. Jeżeli ktoś nie wie jak działa String#next:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Niestety jeżeli wywołamy #next na ciągu znaków nie zadziała tak jakbyśmy chcieli:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Załóżmy, że nasza aplikacja ma model MediaObject, który posiada tytuł, głosy itd. ale specyficzne informacje n/t obiektu (treść/link etc.) są w innym modelu (Media::Text, Media::Image etc.). Relacja oczywiście jeden-do-jeden. Jeżeli zrobimy to na zasadzie referenced assosiation, czyli relacje rodem z baz SQL, będziemy mieli zawsze n+1 zapytań. Mongoid co prawda obsługuje eager loading, ale nie dla relacji polimorficznych. Co więc możemy zrobić?
Tworzymy model MediaObject:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oraz model Media::Resource - po nim będą dziedziczyć wszystkie modele z modułu Media
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Opcja allow_nil pozwala trzymać w #content pustą wartość. W tym przypadku to bardzo ważne, bo nie wiemy czy napewno wszystkie modele Media będą miały taką metodę. Gdyby nie miały, bez tej opcji model zawrze rzucał by wyjątek. Teraz użycie wygląda tak:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Po zainstalowaniu odpaliłem testy powstającej (a więc narazie niedużej) aplikacji Railsowej (Rails 3.1.3)
Ruby 1.9.2
Ruby 1.9.3
Średnie czasy:
Ruby 1.9.2 =~ 16.69
Ruby 1.9.3 =~ 11.12(!)
A więc różnica ponad 5.5s. Całkiem sporo jak na 140 testów.
Update'ować? Opinie są różne, ale wydaje mi się, że jeżeli ma się dobrze otestowaną aplikację można spróbować. Jeśli testy przejdą to po co tracić codziennie te kilka minut (5s * odpalanie_testów_miliard_razy)?