Próbuje przestawić środowisko z “development” na “production”.
Skompilowałem assety za pomocą:
$rake assets:precompile
W katalogu public/assets pojawiła się masa plików z fingerprintem, chyba wszystkie pliki z app/assets + kopie oryginalnych wersji plików.
Operacja zakończona, serwer odpalony - niestety, Railsy nie chcą czytać tak przygotowanych plików.
Przy próbie załadowanie przez widok prekompilowanego pliku assetu (w moim przypadku jest to grafika .png) serwer wywala błąd:
Testowo w pliku konfiguracyjnym environments/production.rb ustawiłem sobie:
config.assets.compile = true
i wtedy serwer działa i wyświetla się widok.
Nie do końca odpowiada on widokowi ze środowiska “development” - zgubiły się gdzieś 2-3 definicje klas lub id z css, ale nie wiem sam dlaczego, albo są nadpisywane, może gdzieś mam konflikt nazw.
No, pytanie jest oczywiste - co robię źle?
Dodam tylko, że szukałem poprzez googla i nie znalazłem odpowiedzi.
No, znalazłem - wszyscy radzą ustawienie:
config.assets.compile = true
ale nie jest to odpowiedź która mnie satysfakcjonuje.
Dodatkowe pytanie natury filozoficznej: czy przestawienie środowiska z “development” na “production” nie powinno się odbywać z trochę mniejszymi problemami?
Jeśli działa w jednym, dlaczego nie chce działać w drugim?
Namierzyłem problem dokładniej: problem plików graficznych PNG, które mam ładowane dynamiczne z layoutu strony.
Mam w kodzie widoku zaszyte coś takiego:
#{@account.status}.png
gdzie @account.status to liczba dodatnia w przedziale od 1 do 15.
W zależności od rekordu w bazie przyjmują wartości od 1 do 15, czyli otrzymują nazwę np. 11.png
I te pliki nie chcą mi się ładować.
Sprawdziłem :CSS’y i JS’y się skompilowały i teoretycznie ładują.
Środowisko, w którym wykonuje się assets:precompile nie ma znaczenia, bo w środku i tak jest zmiana na production (ale lepiej dodać RAILS_ENV=production RAILS_GROUPS=assets, wtedy unikamy ponownego uruchomienia rake’a)
W jakim katalogu masz te obrazki?
Powinno, ale niestety assets pipeline nie jest najlepiej zaimplementowanym feature’em.
Przed kompilacja leżą one w:
app/assets/images
oraz cześć w podkatalogu
app/assets/images/icons
Zresztą, przeniosłem nawet te z “icons/” katalog wyżej i zmieniłem ścieżkę dostępu w widoku i nic to nie dało.
Używam image_tag, chociaż próbowałem też image_path wg znalezionej porady przez googla, niestety ciągle nie widać efektu.
Same obrazki się kompilują, bo w katalogu
public/assets/
pojawiły się pliki graficzne, np:
11.png oraz 11_09832643hf09g8hf9y23bc0ijun2c02ubv902ry.png (piszę z pamięci fingerprint bo nie mam dostępu do serwera)
Czyli wnioskuję, że operacja kompilacji objęła też pliki graficzne, te nawet, których Railsy nie chcą teraz załadować, chociaż grzecznie sobie leżą w katalogu public/assets/
edit:
Dodam tylko, że problem dotyczy wyłącznie plików, których nazwy są generowane dynamicznie przez kod ruby/rails w widoku.
Sprawdziłem to: zakomentowałem te fragmenty, które generowały dynamicznie nazwy plików i aplikacja ruszyła w trybie “production” bez problemów, wyświetla wszystkie css, js i graficzne pliki, których nazwy są wbite na sztywno w layoucie.
Sprawdziłem też manifest.yml - deklaracje nazw wszystkich plików graficznych z “assets” są tam załączone.
Czyli problem polega na tym, że nie mogę w trybie “production” używać generowanych dynamicznie nazw plików?
W ogólności, możesz używać dynamicznie generowanych nazw plików.
W praktyce, mogę Ci zasugerować debugging. Sprawdź jaki URL generujesz (np. zamiast wyświetlania obrazka, wyświetl po prostu wygenerowaną ścieżkę) i czy odpowiada on dokładnie ścieżce, w której leży obrazek (pisałeś, że jest z prefixem /assets).
I dzięki za potwierdzenie, nie wiem, czy jest to optymalne rozwiązanie i eleganckie, ale znalazłem taki sposób generowania nazw plików w jednym z projektów i namiętnie używam tego rozwiązania do generacji różnych elementów w widokach.
<%= image_tag("icons/#{@account.status}.png ") %>
Pliki leżą w app/assets/images/icons/
Po prekompilacj pojawiają się ich wersje w katalogu public/assets/icons/
Są też w manifest.yml
Sprawdzę jutro, jedno czego nie rozumiem, że wszystko ładnie działa w środowisku “development” a w “production” mam z tym problem.
Jest już jutro, to dopowiem tylko, że babola znalazłem, w tym fragmencie kodu, który zacytowałem drogus’owi.
Składnia jest poprawna, przynajmniej działa, ale niechlujstwo piszącego (czyli mnie) doprowadziło do takiej historii.
Chodzi konkretnie o ten fragmentg "
który powinien wyglądać tak: g"
Ruby nie jest wrażliwy na białe znaki, tak jak Python, dlatego działało to w środowisku developerskim.
Podczas prekompilacji assetów generowany jest fingerprint, czyli suma kontrolna plików, a prawdopodobnie string ze spacją ma inną sumę kontrolną niż bez spacji.
Tutaj prawdopodobnie tkwił problem.
Piszę prawdopodobnie, bo nie znam dokładnie mechanizmu sprawdzania sumy kontrolnej jaką dokonuje serwer podczas działania.
Takie moje gdybanie, ale chyba tutaj tkwiła przyczyna niedziałania serwera w środowisku produkcyjnym, podczas gdy działał w developerskim.
Jeśli jednak ktoś chce mnie wyprostować, to bardzo proszę.