Funckja "render :layout => false" ignorowana?

Witam wszystkich użytkowników Railsa - jestem początkującym programistą tego przyjemnego framework’a. Obecnie podszkalam się w “ajaksowaniu” aplikacji z pomocą materiału zawartego w “Ajax on Rails” autorstwa Scotta Raymonda i natknąłem się na mały problem:

W jednej z lekcji konstruuję HTMLowy formularz, przyjmujący pojedynczą linijkę tekstu, która po przesłaniu formularza ma być wypisana od końca, w skojarzonym z funkcją formularza paragrafem:

<% form_remote_tag :update => 'reversed', :url => {:action => 'reverse'} do %> <p><%= text_field_tag 'text_to_reverse' %></p> <p id='reversed'></p> <p><%= submit_tag 'gogogo' %></p> <% end %>
W kontrolerze znajduje się metoda:

def reverse @reversed_text = params[:text_to_reverse].reverse render :layout => false end
Sama metoda i forma działają poprawnie, poza linijką “render (…)”, co powodyuje, że zamiast wypisać mi odwrócony string, jako prosty, zwykły tekst, paragraf wyświetla całą stronę z jej layoutem, tak, jakby :layout => false w ogóle nie działało.

Próbowałem znaleźć jakąś odpowiedź w necie, parę takich przypadków znalazłem, ale odnosiły się wszystkie do Railsa starszego niż zainstalowany u mnie 2.3.2.

Czy ktoś potrafiłby wytłumaczyć gdzie jest błąd, czy też potrzebowalibyście więcej danych?

render :layout => false na 100% działa w Rails 2.3.2

To co się może u Ciebie dziać to w akcji render wyskakuje wyjątek i wyświetla się cała strona z layoutem i szczegółami błędu, widzisz coś takiego ?

O, nawet chyba go zlokalizowałem w Twoim kodzie:

W formularzu masz text_field_tag ‘text_to_reverse’ ale w akcji próbujesz odwrócić string’a znajdującego się w text_toreverse (który nie istnieje i najprawdopodobniej .reverse rzuca wyjątkiem, który wyświetla cały layout, tzn. render :layout => false nigdy się nie wykonuje)

W wersji 2.1.0 (ktora mam zainstalowana w pracy) działa:

render :nothing => true

[quote=tusla]W wersji 2.1.0 (ktora mam zainstalowana w pracy) działa:

render :nothing => true

[/quote]
render :nothing => true to nie to samo co render :layout => false

:nothing => true nic po prostu nie wyświetla, layout => false wyświetla to co zwróci akcja ale nie dekoruje tego layoutem - różnica jest zasadnicza :slight_smile:

hosiawak
tak masz racje, dzisiaj mam nieteges dzien

pozdrawiam

Nie, nie - przepraszam, ale to akurat moja wina. Miałem kod źródłowy na innym kompie niż ten, na którym pisałem posta, więc pisałem “z palca”. W kodzie metody jest poprawnie:

def reverse @reversed_text = params[:text_to_reverse].reverse render :layout => false end
W paragrafie zostaje wyświetlony cały layout strony, ale chyba wyjątku żadnego nie ma przy samej metodzie .reverse, bo podany ciąg znaków jest poprawnie wyświetlony od tyłu.

Pozwolę sobie wtrącić screen’y.
przed wysłaniem formularza:

po wysłaniu:

Daj cały widok formularza. Cos w nim zepsules.

Wypiszę wszystkie (mam nadzieję) pliki biorące udział w konstruowaniu tego zadania:
(przy okazji, czy jest jakaś możliwość podświetlania na tym forum składni plików rhtml / html.erb ?)

app/views/chapter3/index.html.erb

[code=ruby]

Chapter3#index


<%= link_to_remote “Sprawdź godzinę, plix”, :update => “time”, :url => {:action => ‘get_time’},
:confirm => ‘orly?’, :before => “$(‘time’).update(‘loading…’)” %>

<% form_remote_tag :update => ‘reversed’, :url => {:action => ‘reverse’} do %>

<%= text_field_tag ‘text_to_reverse’ %>



<%= submit_tag ‘gogogo’ %>


<% end %>[/code]
app/controllers/chapter3_controller.rb

[code=ruby]class Chapter3Controller < ApplicationController
def index
end

def get_time
sleep 2
render :text => Time.now.to_s
end

def repeat
render :text => params.inspect
end

def reverse
@reversed_text = params[:text_to_reverse].reverse
render :layout => false
end
end[/code]
app/views/chapter3/reverse.html.erb

[code=ruby]

Chapter3#reverse

<%= @reversed_text %>

[/code] app/views/layouts/[b]application.html.erb[/b] [code=ruby] Ajax on Rails <%= javascript_include_tag :defaults %> <%= stylesheet_link_tag "application" %>

Ajax on Rails

<%= yield %> [/code]

[code=ruby]

Chapter3#index

<%= link_to_remote "Sprawdź godzinę, plix", :update => "time", :url => {:action => 'get_time'}, :confirm => 'orly?', :before => "$('time').update('loading...')" %>

<% form_remote_tag :update => ‘reversed’, :url => {:action => ‘reverse’} do %>

<%= text_field_tag ‘text_to_reverse’ %>


<%= submit_tag ‘gogogo’ %>


<% end %>
[/code]

Dzięki sowiak, ale nie o to chodzi.
Chcę wypisać wynik metody reverse jako zwykły tekst, pod istniejącymi już elementami html. Twoje rozwiązanie natomiast, polega na zamianie istniejącego układu na układ reverse.html.erb.
Co więcej: mimo iż w funkcji jest jak byk…

render :layout => false

…u mnie nadal wykorzystywany jest plik layout’u.

Sprawdzałem, czy działają inne atrybuty metody render i na przykład

render :nothing => true

działa tak, jak powinno (ergo - na stronie nie pojawia się nic nowego).

Próbowałem też znaczniki zamienić na DIVy, bez efektu.

Zaczynam sądzić, że coś na moim kompie zwyczajnie nie rozumie tej funkcji, jakby było przestarzałe, ale zarówno Ruby i wszystkie gemy do Railsa były instalowane w zeszłym miesiącu.

No mam zagwozdkę jak cholera.

render :text => @reverse

Chociaz nie wiem, czy zadziala.

render :layout => false

dotyczy glownego layoutu (katalog layouts), nie layoutu widoku.

edit:

Widoki sa od serwowania tresci, wiec teoretycznie nie powinno sie ich omijac.

[quote=sowiak]render :text => @reverse
[/quote]
Akurat musiałoby być:

render :text => @reversed_text

Dzięki wielkie , pożądany efekt uzyskany; ale nadal trochę martwi mnie to, że nie działa :layout => false. Utworzyłem nawet pusty plik, bez żadnego stylu, podałem jego nazwę w :layout => “empty”, a i tak został olany.

bo w widoku akcji reverse dla kontrolera Chapter3Controller masz

[code]

Chapter3#reverse

<%= @reversed_text %>

[/code]

[quote=sowiak]bo w widoku akcji reverse dla kontrolera Chapter3Controller masz

[code]

Chapter3#reverse

<%= @reversed_text %>

[/code] [/quote] Nie widzę w tych dwóch linijkach niczego, co stanowiłoby o stylu dokumentu, paragraf po prostu przejmuje domyślny styl, ustalony w [b]application.html.erb[/b] i właśnie to staram się zatrzymać metodą [b]render :layout => false[/b]

wow, strasznie dużo postów, a z każdym następnym coraz więcej nieporozumień :slight_smile:

@ellmo: miałem chwilkę wolnego i zrobiłem ctrl+c, ctrl+v. Sytuacja u mnie wygląda tak samo jak u Ciebie na screenie, ale bynajmniej to nie jest błąd. To, co określiłeś “W paragrafie zostaje wyświetlony cały layout strony” - to bzdura. W paragrafie zostanie wyświetlona zawartość widoku reverse.html.erb! A dlaczego tak wygląda? Widocznie masz tak ustawione w kaskadowych arkuszach stylów (selektor h1, np. background: jakis_kolor).

Poza tym, zauważ, twój plik layout definiuje tylko podstawowe rzeczy (typu: znacznik title, <%= javascript_include_tag :defaults %> - odpowiedzialny za dołączenie m.in prototype do dokumentu, <%= stylesheet_link_tag “application” %> - dołaczęnie kaskadowych arkuszy stylów). Natomiast do <%= yield %> zostanie wczytana zawartość plików widoku (np. jeśli zostanie wywołana akcja foo, yield wyświetli zawartość widoku foo.html.erb)

To tyle. Mam nadzieję, że nie namieszałem :slight_smile:

Pozdrawiam

Ha, no tak. Teraz rozumiem, niepotrzebnie umieszczałem znacznik

, bo nawet jeżeli ignoruję styl z reverse.html.erb, to zostaje styl w index.html.erb, który załączy się do tego nagłówka.

Obaj macie rację, i chciałbym zwrócić honor sowiakowi :]

Nic sie nie stalo, poprostu ‘nie bylem w stanie’ dzis pisac jasniej.