Przyjazne URLe (w postaci: server.com/blog/123-tytul-bloga) w dowolnej aplikacji można w Railsach uzyskać bardzo łatwo. Cała pseudo-sztuczka opiera się na fakcie, że jeśli ID rekordu zaczyna się od cyfr, ActiveRecord wycina sobie tylko cyfry z początku ciągu znaków. Czyli wywołanie
niczym się nie różni od
1
| @blog = Blog.find("123-tu_jakis_tytul") |
By uzyskać przyjazne URLe w aplikacji, do modelu należy dodać metodę to_param:
1
2
3
| def to_param
"#{id}-#{title.parameterize}"
end |
Tak byłoby jednak za prosto – railsy nie radzą sobie z literami “ł” i “Ł”. Poniżej więc proste obejście tego (wrzucić do pliku config/initializers/active_support.rb):
1
2
3
4
5
6
7
8
9
10
11
| module ActiveSupport
module CoreExtensions
module String
module Inflections
def parameterize(sep = '-')
Inflector.parameterize(self.gsub("ł", "l").gsub("Ł", "L"), sep)
end
end
end
end
end |
Chwilę sposobu na wciśnięcie jednego obrazka nad drugi szukałem, więc podam rozwiązanie tu.
W sklepie OTTO Polska mieliśmy wprowadzić obsługę promocji oraz odpowiedniego informowania o tym klienta. I chodziło nie tylko o przedstawienie banalnych przekreślonych cen, co dodatkowy znak/ikonę nad zdjęciem produktu – tak, by promocja maksymalnie rzucała się w oczy. Problem z całym zagadnieniem polegał na tym, że nie byliśmy w stanie przygotować gotowych zdjęć z naniesionym już znakiem, a i w kodzie nie mieliśmy ochoty specjalnie babrać. Rozwiązania chwilę szukałem, ale jedyne co znalazłem to ponoć skuteczne rozwiązanie z wykorzystaniem parametru background (dla obrazka który de-facto ma być naniesiony dodajemy background, w ramach którego wstawia się oryginalne zdjęcie. Bez sensu.). Rozwiązania, które znalazłem w pierwszej kolejności po prostu zdecydowanie mnie nie usatysfakcjonowały (link).
Oto co my zrobiliśmy:
1
2
3
4
| <a href="produkt">
<img src="photo.png" border="0" alt="" width="255" />
<img style="position: absolute; margin-left: -54px; z-index: 100;" src="reduced.gif" alt="" />
</a> |
Okazuje się, że liczy się kolejność (wpierw zdjęcie, potem ikona) i zasadniczo tylko parametry z-index i position. Margin tylko odpowiednio ustawia ikonę.
Efekt końcowy:

Ostatnio na specjalne życzenie klienta przygotowaliśmy bibliotekę importującą kontakty z książek adresowych darmowych kont pocztowych najpopularniejszych polskich portali (Interia.pl, Wirtualna Polska, O2.pl, Gazeta.pl i Gmail.com). Brakuje jeszcze tylko Onetu, ale mam nadzieję, że i to uda się wkrótce obejść.
Biblioteka napisana jest w Ruby, rzuca wyjątkami, itd, ale przynajmniej działa. Jej głównym zadaniem jest taki import znajomych, by dało się przedstawić ich listę użytkownikowi, by ten mógł zaprosić swoich znajomych do serwisu.
Uwaga – biblioteka wymaga nokogiri, mechanize i fastercv.
Do pobrania z Githuba, na razie trzeba klonować. Gdy uda się zaciągnąć kontakty z Onetu, pewnie Gem powstanie.
http://github.com/galdomedia/addr_book_importer_pl/tree/master
Uwaga: nie wiem na ile wykorzystywanie tej biblioteki jest zgodne z regulaminami portali, z których kontakty są importowane. Dostarczamy narzędzie, ale nie odpowiadamy za wszelkie skutki jego stosowania!
Po pewnych bojach udało mi się zmusić do działania aplikację w Pylons, by działała pod mod_passenger. Kody przykładowej aplikacji wrzuciłem na githuba. Ot, może komuś się przyda i zaoszczędzi trochę cennego czasu.
Warto chyba tylko dodać, że kluczowy jest plik passenger_wsgi.py, który odpowiada za całą magię.
Wpis ukazał się również na blogu osobistym.
Po roku od oficjalnego założenia firmy naszło mnie na wnioski. Naszło mnie na wiele wniosków, bo to idealna okazja do tego. Tu spiszę tylko najważniejsze punkty, którymi warto ie kierować i których musiałem się w większości sam nauczyć. W zdecydowanej większości boleśnie. Punktując jednak wnioski (chaotycznie, wiem):
- własna firma to zdecydowanie dobra rzecz. Najlepsza, jeśli nie lubisz słuchać nie-do-końca słusznych uwag Państwa Przełożonych
- zanim zatrudnisz kumpla, zastanów się dwa razy
- zanim powiesz kumplowi, że chcesz go zwolnić, zastanów się trzy razy
- zanim faktycznie zwolnisz kumpla, ustal bardzo dokładnie warunki rozstania
- każdego klienta traktuj poważnie, każdego
- jeśli klient cię faktycznie denerwuje, traktuj to jak test charakteru. Po pół roku będziesz się z tego śmiać, a całość zaliczysz do zbioru cennych doświadczeń
- samemu nie ogarniesz połowy istotnych spraw
- rozliczaj się możliwie szybko ze wszystkimi współpracownikami
- pamiętaj, że im większa firma, tym ciężej od niej wyciągnąć pieniądze
- nie próbuj zrobić więcej, niż realnie jesteś w stanie
- gdy znajomej firmie o podobnym profilu wiedzie się lepiej, nie bądź zazdrosny. Rywalizuj. Rywalizacja jest zdrowa, to konkurencje się tępi
- bądź otwarty i nie dyskwalifikuj ludzi od razu – cierpliwie wysłuchaj co mają do powiedzenia, bo zawsze może się z tego wykluć coś ciekawego
- zapomnij o terminach “8-godzinny dzień pracy”, bądź “40-godzinny tydzień pracy”
- niedziela to *był* dzień wolny do momentu założenia firmy
- dzień wolny zacznij w ogóle traktować jako termin abstrakcyjny
- …z drugiej strony pamiętaj, że ludzie z którymi pracujesz, mogą mieć trochę inny na to pogląd
- i pamiętaj – znajdź swój cel w tym, co robisz… Bo może tak jak my dziś i ty któregoś pięknego dnia dostaniesz zlecenie z agencji modelek
Raz na jakiś czas udaje nam się z powodzeniem skończyć jakiś własny, bądź wspólny projekt. Tym razem wypuszczamy w świat Szuflera – serwis z krótkimi, bo maks 160-znakowymi, recenzjami tego, co przeczytaliście, obejrzeliście, przesłuchaliście, bądź w co graliście. Liczymy na to, że się spodoba.
Serwis udało się stworzyć tak na prawdę dzięki Arturowi Kurasińskiemu oraz chłopakom z Centrologic, którzy niestety nie mogli poprowadzić całości do końca. Padło na nas, za co jesteśmy bardzo wdzięczni i z czego jesteśmy bardzo dumni. Osobne kudos dla Michała Bieleckiego, towarzysza broni w soim czasie, który pamiętając, właśnie nam zaproponował dokończenie projektu. Dzięki!
O Szuflerze więcej możecie poczytać na blogu Artura.
Notka pisana raczej jako “note-to-self”, ale może ktoś kiedyś również będzie miał z tym problemy.
Po wrzuceniu aplikacji na serwerze (już po użeraniu się z DirectAdminem i niedziałającym PDO), aplikacja zamiast kulturalnie porozmawiać, postanowiła się wywrócić i krzyczeć, że “There is already an active transaction”, czyli że niby już rozpoczęta została wcześniej jakaś transakcja. Problem w tym, że kod poprawnie działał na trzech, całkowicie niezależnych maszynach deweloperskich. Coś więc było nie tak. Teoretycznie rozwiązanie jest podane w manualu PHP, jednak nie w sposób bezpośredni. Rozwiązanie jest banalne:
1
| $dbh->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, true); |
Nauczyło nas to jeszcze, że warto umieszczać w aplikacji następującą klauzulę:
1
| $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); |
dzięki której PDO zgłaszając błędy, robi to w sposób bardziej zrozumiały.
Ostatni update Railsów do wersji 2.1.2 (z 2.1.0 bodajże) spowodował, że pewien fragment pisanego systemu przestał działać – konkretnie stało się coś z wysyłaniem zagnieżdżonych form. Forma zamiast się kulturalnie wysłać i zapisać, bądź mniej kulturalnie wysłać się i rzucić pięknym, czytelnym błędem, ta zaczęła ordynarnie rzucać statusem 500 Internal Server Error (“nie pogadasz”). Wprowadziło nas to w lekką konsternację, bo nie często się zdarza, by aplikacja Rails w trybie development aż tak brzydko się zachowywała. Jedyną rzeczą, która była w stanie naprowadzić nas na przyczynę, był ostatni komunikat w konsoli:
Conflicting types for parameter containers. Expected an instance of Hash but found an instance of Array. This can be caused by colliding Array and Hash parameters like qs[]=value&qs[key]=value. (The parameters received were [{"sex"=>"M", "first_name"=>"Maciej", "last_name"=>"Litwiniuk"}].)
Zatem coś z parametrami. Nie udało się tego jednak łatwo zdebugować – aplikacja po prostu rozkładała się na łopatki, zanim zdążyła poprawnie wstać. Googlanie jednak pozwoliło znaleźć rozwiązanie, raczej banalne w swej prostocie – błąd powodowało pole date_select, które nagle zaczęło się błędnie renderować w zagnieżdżonych formach – nie dodawało znacznika tablicy ([]), co skutkowało właśnie wyjątkiem krytycznym – Railsy faktycznie w parametrach dostawały mieszaninę Hasha i tablicy.
Rada? Dodać parametr :index=>'' do wywołania date_select, które wymusza wstawienie indeksu w nazwie pola. Jego pusta wartość (NIE nil) powoduje, że pole zostanie wygenerowane poprawnie.
Przykład:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| <% fields_for "subscription[member_attributes][]", member do |m| %>
<td><%= m.select(:sex, {'Meżczyzna'=>'M', 'Kobieta'=>'K'}) %></td>
<td><%= m.text_field :first_name %></td>
<td><%= m.text_field :last_name %></td>
<td width="50">
<%= m.date_select :birthdate,
:start_year => 1900,
:use_month_numbers => true,
:order => [:day, :month, :year],
:end_year=>Time.now.year,
:default=>{:year=>1990},
:class=>"dateselect",
:index=>'' %>
<%= link_to_function image_tag("icon_delete.gif", {:border=>0}), "$(this).parent('td').parent('tr').remove();prices_for_participants();" %></td>
</td> |
Warto wiedzieć, że istnieje różnica pomiędzy opcjami “Pokaż źródło”, a “Pokaż źródło zaznaczenia” dostępnymi w przeglądarkach Firefox.
Pokaż źródło (dostępne spod Ctrl+U lub Cmd+U) wyrzuca źródło strony, które zostało wygenerowane przez serwer. Jest to źródło statyczne, “czyste”, nie tknięte przez różnego rodzaju operacje JavaScriptowe (przesunięcia / ukrywanie / ładowanie treści via AJAX / etc). Podgląd ten pomocny jest zwłaszcza, gdy chcemy sprawdzić, czy strona została wygenerowana poprawnie, czy pliki JS, bądź CSS mają poprawne ścieżki, itd.
Pokaż źródło zaznaczenia dostępne jest w menu kontekstowym (prawy przycisk myszy) po zaznaczeniu treści na stronie. Pokazane źródło to kod, który już wyświetla przeglądarka – czyli po wszelkich dynamicznych operacjach. Jest to kod zinterpretowany przez przeglądarkę, zgodnie z którym strona została wygenerowana.
Najświeższe komentarze