Kontrolery i moduły

Witam,

Mam coś takiego:

/controllers /admin foo_controller.rb
Teraz gdy wklepie url: http://127.0.0.1:3000/admin/foo

i dam

<%= params[:controller'] %>

zostanie wyswietlone “foo” zamiast “admin/foo”. Jak grzecznie poprosić railsy, aby zwróciły nam pełną nazwę kontrollera? Potrzebne jest mi to do zmiany języka na stronie. Mam ikonki [pl] [en] [de] i chce, aby po kliknięciu na ikonkę z językiem strona przeładowała się i była w nowym języku.

  1. Mamy stronę /pl/admin/foo
  2. Klikamy na ikonkę [en]
  3. Mamy stronę /en/admin/foo

Chcesz języki robić na osobnych kontrolerach? To raczej bez sensu. Spróbuj tak. Dodaj do routes.rb:

map.connect ":lang/:controller/:action/:id", :requirements => { :lang => /pl|en|de/ }

Teraz będzie Ci łapać wszystkie wpisy w stylu “/pl/books”, “/pl/books/list”, “/en/clients/show/1”, a nawet zagnieżdżone kontrolery “/pl/admin/clients/show/20”. Tutaj masz na sztywno 3 języki wpisane w routes, ale może usunąć to ograniczenie i obsłużyć sobie dany język w kontrolerze lub filtrze (params[:lang]).

Mam nadzieję, że pomogło.

Nie do końca o to mi chodziło. Mam kontroler “admin/article” i w nim akcję, powiedzmy index.

Gdy piszę:

params[:controller]

To wyświetli mi “article” zamiast “admin/article”. Dzieję się tak ponieważ routes mam zdefiniowane następująco:

[code] map.connect ‘/:lang/:controller’
map.connect ‘/:lang/:controller/:action’
map.connect ‘/:lang/:controller/:action/:id’
map.connect ‘/:lang’, :controller => ‘index’
map.root :controller => ‘index’, :lang => ‘pl’

map.connect ‘admin’, :controller => “admin/index”, :action => “index”, :lang => “pl”
map.connect ‘:lang/admin/’, :controller => “admin/index”, :action => “index”
map.connect ‘:lang/admin/:controller’
map.connect ‘:lang/admin/:controller/:action’
map.connect ‘:lang/admin/:controller/:action/:id’[/code]
Gdy jesteśmy w “admin/article” wybieramy zmianę wersji językowej (powiedzmy PL zamieniamy na EN) klikając w ikonkę z linkiem. I teraz jak zrobić, aby strona się przeładowała (ten sam kontroler, ta sama akcja - zmienia się tylko język).

/pl/admin/article => user klika [EN] => /en/admin/article/

Ponieważ w definicji trasowania (przez co rozumiem routes.rb) nie można odwołać się do aktualnych wartości parametrów (a może się da?), to konieczne jest zastosowanie dodatkowego parametru, który będzie ustawiany, kiedy wywoływany jest kontroler zagnieżdżony (tzn. admin/costam). Rozwiązanie nie jest bardzo eleganckie, ale powinno działać.

[code=ruby]# routes.rb
map.connect ‘:lang/admin/:controller’, :admin => “admin”

podobnie pozostałe

jakiś widok lub kontroler

(params[:admin].nil? ? “” : “admin/”) + params[:controller][/code]
Swoją drogą sam jestem ciekaw, czy da się to rozwiązać w bardziej elegancki sposób.

y3ti, nie musisz znać nazwy i url kontrolera, RoR go zna, twoje routes.rb są OK, wystarczy:

<%= link_to ‘English’, url_for(:overwrite_params => {:lang => ‘en’}) %>
<%= link_to ‘German’, url_for(:overwrite_params => {:lang => ‘de’}) %>

url_for wygeneruje aktualny zestaw params a ty musisz tylko nadpisać ten na którym ci zależy ( w tym wypadku :lang)

Jeśli :lang znajduje się w routes.rb (np. /:lang/:controller/:action) to url_for go podmieni na /en/:controller/:action
Jeśli :lang nie ma akurat w routes.rb dla danej akcji to zostanie dopisany (np. /articles/show/1?lang=en

Mam nadzieję, że to pomoże, powodzenia w odkrywaniu Railsów :slight_smile:

Skąd ta tendencja do namespace’owania kontrolerów? :slight_smile:
http://www.caboo.se/articles/2006/7/1/if-your-models-arent-namespaced-why-should-your-controllers-be-or-how-i-learned-to-stop-worrying-and-love-the-crud

Swoją drogą język o wiele lepiej ustawić raz “na wsiegda” w sesji, do internacjonalizacji serwisu polecam Globalize.

Pytań ciąg dalszy :slight_smile:

Piszę teraz panel do dodawania nowej firmy do bazy danych.
/pl/admin/company/new

po wypełnieniu formularza lecimy do /pl/admin/company/create

[code] def create
@company = Company.new(params[:company])

if @company.save
  redirect_to :action => "show", :id => @company.id
else
  render :action => "new"
end

end[/code]
i mnie przenosi do /pl/admin/admin/company/show/5 zamiast do /pl/admin/company/show/5

Co ciekawe jeśli dam redirect bez :id

redirect_to :action => "show"

to działa dobrze (tj. nie dodaje 2 razy admin). Co jest tego powodem?

Kod jest ok, na jego podstawie nic nie wynika. Na moje oko powinieneś szukać błędu w routes.rb. Patrząc na Twoje routes we wcześniejszym poście wydaje mi się, że definiujesz je w złej kolejności. Te bardziej szczegółowe powinny być na samym początku. Dodatkowo radzę Ci wyłączyć defaultowe wpisy, czyli tego typu “map.connect ‘:controller/:action/:id’”. Ja mam wpisy typu:

map.admin_clients               'admin/clients/:action/:id',            :controller => 'admin/clients'

I wszystko działa dobrze. W ten sposób muszę mieć po jednym wpisie dla każdego kontrolera, ale nie jest to problemem póki aplikacja nie ma kontrolerów w setkach ;).

Pomogło Twoje rozwiązanie :slight_smile: