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> |
Najświeższe komentarze