Rails 3.1.3 i Ajax

Od pewnego czasu piszę aplikację (zaczynałem z RoR 3.0) i wszystko ładnie działało do czasu przejścia na RoR 3.1.3. Pojawiły się problemy z Ajax-em. Same zapytania są poprawnie przekazywane do serwera, serwer je wykonuje, renderuje widoki i wysyła do przeglądarki. I tu pojawia się problem. W odpowiedzi brakuje nagłówka Content-type: text/javascript i przeglądarka nie wykonuje zwróconego javascriptu. Do tej pory robiłem to mniej więcej tak:

[code=ruby]def akcja

jakiś kod

respond_to do |format|
format.js { render :layout=>false }
end
end[/code]
Teraz to nie działa :frowning:
Jedyne co udało mi się wykonać:

[code=ruby]def akcja

jakiś kod

respond_to do |format|
format.js { render :js=>“alert(“Zrobione”)”, :content_type => ‘text/javascript’, :layout=>false }
end
end[/code]
To jednak nie jest rozwiązanie bo czasami muszę całkiem spore dane przekazać do przeglądarki.
Samo dodanie :content_type => ‘text/javascript’ nie rozwiązuje problemu. Wygląda to tak jakby przy renderowaniu pliku akcja.js.erb RoR zapominał, co ma wysłać.

Jak sobie z tym poradzić? Gdzie szukać rozwiązania problemu?

Przyczyn należy szukać w widoku najprawdopodobniej. Gdy ostatnio robiłem ajaxy, to wystarczyło dać w formie:

= form_for @resource, :remote => true do |f|

Jeśli obsługujesz to jakoś inaczej (chociaż mimo wszystko lepiej spróbować z opcją :remote), to możesz spróbować użyć data-type:

= form_for @resource, :html => { :'data-type' => :script } do |f|

jak wygląda (i jak się nazywa) widok akcji “akcja”?

Więc po kolei:

  • w widoku app/views/articles/show.html.erb
<%= link_to "Przeczytano", read_articles_path(@article), :id=>'articles_read', :remote=>true %>
  • w kontrolerze app/controllers/articles_controller.rb

def read @article = Article.find params[:id] current_user.articles << @article response_to do |format| format.js { render :layout=>false } end end

  • w widoku app/views/articles/read.js.erb

$("#articles_read").remove() alert("Dodano do przeczytanych")
Jedną z przyczyn jest rack-1.3.5/lib/rack/conditionalget.rb. Wystarczyło do link_to dodać :method=>:post (i oczywiście zmiany w routes.rb) i nagłówek Content-type już się pojawia. Jednak zwracany skrypt nadal się nie wykonuje. Może przyczyna leży w jquery-rails? Wykorzystuję wersję 1.0.15.

I sprawa się wyjaśniła. Problemem nie jest RoR tylko konsola Firefox-a, która nie wyświetla informacji o błędach w AJAX-ie.

W kodzie miałem:

alert("<%= t("articles.read.Article_readed",:resource=>@article.title) %>")

Ale tłumaczenie nie było dostępne. Zatem alert zawierało string

<span title="translation articles.read.Article_readed">Article readed</span>

W efekcie otrzymywałem błąd: Parse error unterminated string literal, który powinien pojawić się w konsoli FF a nie było go (znalazłem analizując krok po kroku działanie w Firebug-u). Javascript bardzo nie lubi znaku / i to on powodował błąd.

Po dodaniu tłumaczenia i zmodyfikowaniu pliku read.js.erb działa jak należy.

[code=ruby]# plik config/locales/pl/views.yml
pl:
articles:
read:
Article_readed: “Artykuł \”%{resource}\"\ndodano do przeczytanych"

plik app/views/articles/read.js.erb

$("#articles_read").remove()
alert("<%= t(“articles.read.Article_readed”,:resource=>@article.title).html_safe %>")[/code]

[quote=Tuptus]<span title="translation articles.read.Article_readed">Article readed</span>
[/quote]
A propos w języku angielskim nie ma “readed” http://www.angielski.slowka.pl/gramatyka,czasowniki-nieregularne-irregular-verbs,m,558.html