2013-03-16 3 views
5

Aplikacja Moja Ruby on Rails ma model DocumentType i model PersonType. Dokument ma typ DocumentType (np. Letter, Postcard) i zawiera listę jednego lub więcej osób. Każda osoba ma przypisany PersonType do reprezentowania ich związku z Dokumentem (nadawca, odbiorca, autor itp.). Użytkownik może przypisywać osoby tylko do PersonTypes odpowiednich dla typu DocumentType.Formularz checkbox w Ruby on Rails oparty na relacji wiele-do-wielu

definicje Tabela:

create_table "document_types", :force => true do |t| 
t.string "name" 
end 

create_table "document_types_person_types", :id => false, :force => true do |t| 
t.integer "document_type_id" 
t.integer "person_type_id" 
end 

create_table "person_types", :force => true do |t| 
t.string "name" 
end 

model definicje:

class Document < ActiveRecord::Base 
has_many :people, :dependent => :destroy 
belongs_to :document_type 
end 

class DocumentType < ActiveRecord::Base 
has_many :documents 
has_and_belongs_to_many :person_types 
end 

class Person < ActiveRecord::Base 
belongs_to :document 
has_and_belongs_to_many :person_types 
end 

class PersonType < ActiveRecord::Base 
has_and_belongs_to_many :people 
has_and_belongs_to_many :document_types 
end 

przykłady Tabela:

documents 
id: 1 
document_type_id: 1 
name: Letter from John Smith to Jane and Joe Smith 

document_types 
id: 1 | name: letter 

document_types_person_types 
document_type_id: 1 | person_type_id: 1 
document_type_id: 1 | person_type_id: 2 
document_type_id: 1 | person_type_id: 4 

person_types 
id: 1 | name: Sender 
id: 2 | name: Recipient 
id: 3 | name: Photographer 
id: 4 | name: Author 

people 
id: 1 | document_id: 1 | name: John Smith | person_type_id: 1 
id: 2 | document_id: 1 | name: Jane Smith | person_type_id: 2 
id: 3 | document_id: 1 | name: Joe Smith | person_type_id: 2 

Gdy użytkownik jest dodanie osoby do dokumentu, będą one wybrać, które z związek, który Osoba jest z Dokumentem, i który będzie przechowywany w modelu Person (lub rozszerzonym mod el).

Dokument będzie zawierał tylko PersonTypy, które są związane z tym typem dokumentu (na przykład zdjęcie nie będzie miało autora, ale będzie miało fotografa).

Więc po tym wszystkim ... Co chcę osiągnąć to interfejs administracyjny dla DocumentTypes, reprezentujący tabelę document_types_person_types który pokazuje wszystkie PersonTypes i pozwala mi wybrać opcję jeśli PersonType ma zastosowanie:

EDIT DocumentType Letter 
Sender  [x] 
Recipient [x] 
Photographer [ ] 
Author  [x] 

Wybrane te PersonTypes będą wówczas jedynymi PersonTypami dostępnymi podczas dodawania Osoby do Dokumentu. Miejmy nadzieję, że bardziej prosto niż moja wyniszczona próba wyjaśnienia mogła reprezentować. Czy ktokolwiek mógłby podać jakieś wskazówki?

edit: Do wykorzystania w przyszłości, na podstawie odpowiedzi Fryderyka poniżej, to pracował

<% for pt in PersonType.find(:all) %> 
    <%= check_box_tag "document_type[person_type_ids][]", pt.id, @document_type.person_types.include?(pt) %> 
    <%= pt.name %> 
<% end %> 

Odpowiedz

2

Z stowarzyszenia jak ta, DocumentType będzie miał person_type_ids metodę, która zwraca tablicę identyfikatorów powiązany typy osób.

Dlatego jeśli utworzyć zestaw pól wyboru, gdzie nazwa jest document_type[person_type_ids][] i których wartość jest id każdej osoby wpisać to co zostanie przedstawiony jest tablicą zawierającą identyfikatory zaznaczonych rodzajów osoby, więc

document_type.update_attributes params[:document_type] 

Zaktualizuje powiązanie. Jedyną subtelnością jest to, że jeśli nie zaznaczono pól wyboru, wówczas nie jest składana żadna tablica (nie można przesłać pustej tablicy), a lista powiązanych typów osób nie zostanie wyczyszczona. Normalnie omijam to poprzez ukryte pole, które dodaje wartość 0 do tablicy (ponieważ wiem, że nigdy nie będzie to prawowity identyfikator), a następnie usunie ją z tablicy w kontrolerze.

+0

Dziękuję bardzo za szybką i pomocną odpowiedź Fredericka. Dam ci to i zgłoś się. –

+0

D'oh, zredagowałem odpowiedź, a nie moje pytanie, ale to, co zadziałało, jest powyżej. –

+0

Cześć, próbowałem jak powyżej, ale otrzymuję ten błąd 'Nie można masowo przypisać chronionych atrybutów:'. Czy masz jakieś sugestie? Dziękujemy – Teo