Witam… znowu.
Nie wiem czy określenie tablica słownikowa jest ogólnie przyjmowane, ale mam nadzieję, że jest przynajmniej zrozumiałe
Próbuję stworzyć widok, który pozwalałby dodać nowy rekord do bazy danych, ale część jego pól jest wybierana (najlepiej z droplisty) bazując na dostępnych wierszach tablicy słownikowej. Bawię się w stworzenie bazy danych pojazdów kosmicznych (taa, wiem :)), w której każdy obiekt posiada pole klasy statku i może przynależeć tylko do jednej z wcześniej zdefiniowanych klas, takich jak niszczyciel, czy krążownik.
Nie wiem jak zmapować tablicę słownikową i jej wartości (id i name), żeby wyświetlały się w dropliście i można je było tam wybrać.
Póki co natkałem się w Agile Web Development(…) na wybieranie jednego z elementów zdefiniowanych wcześniej w zwykłej tablicy.
EDIT: aha, przydałaby się jeszcze jakaś metoda walidacji, sprawdzająca, czy pole rekordu zawiera się w zbiorze elementów tablicy słownikowej.
Helpery select i select_tag łykają tablicę – albo pojedynczych elementów (stringów) które są wtedy etykietą ORAZ wartością (przesyłaną do serwera przy wysłaniu formularza), albo dwuelementowych tablic etykieta-wartość.
Jeśli masz hasha, musisz go najpierw do takiej tablicy skonwertować. Jak – to już sam wybierz
def self.find_all_for_select
self.all.map {|x| [x.name, x.id]}
end
end
kontroler:
@spaceships = Spaceship.find_all_for_select
w widoku (zakładając, że klucz to spaceship_id):
<%= f.select :spaceship_id, @spaceships -%>[/code]
Jeszcze tylko małe sprostowanie do tego co napisał Tomash: helper select_tag nie przyjmuje tablicy etykieta-wartość tylko gotowe option tagi (Jeden) jako html.
Do przygotowywania option tagów z tablicy służy helper options_for_select. Czytajcie dokładnie dokumentację Rails - tam są wszystkie odpowiedzi na takie pytania
Dzięki wielke za odpowiedź,
Miałem małą przerwę od programowania, więc to co opisaliście sprawdzam dopiero dziś. Mam jednak problem, moja lista próbuje wysłać do bazy danych nil:
[code] Showing app/views/vessels/new.html.erb where line #12 raised:
You have a nil object when you didn’t expect it!
You might have expected an instance of Array.
The error occurred while evaluating nil.inject
Extracted source (around line #12):
9:
10:
11: <%= f.label :classtype %>
12: <%= f.select :classtype, @classtypes -%>
13:
14:
15: <%= f.label :classsubtype %> [/code]
Na pewno po prostu porąbałem coś z nazwami, które (jakoś tak się złożyło) są dość niekonsekwentne: w bazie danych przetrzymuję pole classtype, które wybierane jest z tablicy vesseltype, ale żeby od razu nil ? Tak, jakby select wyświetlał tylko dostępne nazwy, ale przy wyborze konkretnej pozycji wcale nie przesyłał jej wartości do bazy.
[/quote]
Wtedy wywala, że nie zna metody classtype_id, pewnie dlatego, że takie pole nie istnieje w tabeli w bazie. Być może rails absolutnie wymaga, żeby pola będące w relacji z innymi tablicami miały końcówki _id, choć mam nadzieję, że nie.
Czyli działać powinno, a ciągle nic z tego.
W ogóle zaskakuje mnie, że widok new próbuje wstrzyknąć obiekt nil do bazy danych, mimo, że są odpowiednie walidacje, upewniające się, że tak nie będzie.
Przykład omawiany w “Agile (…)” z wykorzystaniem tablicy tablic (do wybierania jednej z trzech metod płatności przy zamówieniu - jeśli ktoś przerabiał i wie o czym mówię) jest bardzo podobny. Ja natomiast mapuję tablicę z bazy na tablicę w aplikacji, sprawdzałem jak dokładnie działa to mapowanie, czy wszystko gra, więc poszedłem do konsoli projektu i tam wywołałem: