2010-10-14 13 views
6

Nie jestem do końca pewien, co mój problem jest, więc to pytanie może wymagać trochę więcej wyjaśnień, ale tutaj jest to, co wydaje się być najbardziej istotne:szyny 3 has_many: poprzez zapis zapisać błąd

mam has_many :through i model join ma kilka pól, które nie są kluczami obcymi. Kiedy buduję modele i próbuję zapisać, otrzymuję błąd sprawdzania poprawności na polach klucza obcego z modelu łączenia.

Moje pliki wyglądać następująco:

Person.rb 

    has_many :wedding_assignments, :dependent => :destroy 
    has_many :weddings, :through=>:wedding_assignments 
    accepts_nested_attributes_for :weddings 
    accepts_nested_attributes_for :wedding_assignments 

Wedding.rb 

    has_many :wedding_assignments, :dependent => :destroy 
    has_many :people, :through=>:wedding_assignments 
    accepts_nested_attributes_for :people 
    accepts_nested_attributes_for :wedding_assignments 

WeddingAssignment.rb 

    belongs_to :person 
    belongs_to :wedding 
    validates_presence_of :role, :person, :wedding 

(rola jest ciągiem)

people_controller.rb 

    def new 
    @person = Person.new 

    1.times do 
     wedding = @person.weddings.build 
     1.times do 
     assignment = wedding.wedding_assignments.build 
     assignment.person = @person 
     assignment.wedding = wedding 
     end 
    end 
    end 

    def create 
    @person = Person.new(params[:person]) 
    @person.weddings.each do |wedding| 
     wedding.wedding_assignments.each do |assignment| 
     assignment.person = @person #i don't think I should need to set person and wedding manually, but I get a validation error if I don't 
     assignment.wedding = wedding 
     end 
    end 
end 

params że wracają wyglądać następująco:

{"first_name"=>"", "last_name"=>"", "weddings_attributes"=>{"0"=>{"wedding_assignments_attributes"=>{"0"=>{"role"=>"Bride's Maid", "budget"=>""}}, "date"=>"", "ceremony_notes"=>""}}} 

oraz dokładna błędu:

ActiveRecord::RecordInvalid in PeopleController#create 
Validation failed: Role can't be blank 

co oczywiście nie jest prawidłowy, ponieważ można go zobaczyć w params[]

Co robię źle?

To szyn 3.0.0

+2

Jestem ciekawy, jaki jest pożytek z tych "1-szych"? – PeterWong

+0

Robię to, aby ułatwić, jeśli chcę zmienić go na 2 lub więcej razy później. – SooDesuNe

+0

Masz rację, to może nawet pozwolić użytkownikowi wybrać dodanie 10 wesel za jednym razem. : D – PeterWong

Odpowiedz

0

Spróbuj zmienić „Person.new” na „Person.create”, może tworzyć rekord w db razu pomoże ze stowarzyszeniami.

+0

Zdecydowanie nie chcę ich od razu w bazie danych. Co się stanie, jeśli użytkownik zmieni zdanie i przejdzie poza stronę? Czy nie mam pustego rekordu, jeśli używam "tworzenia"? – SooDesuNe

1

rację, to jest trochę odgadnięcia, więc przeprosiny jeśli skończę tracić czas tutaj ...

ona patrzy na mnie jak w metodzie tworzenia, podczas tworzenia relacji „ślub” (która jest tylko "udawaną" relacją naprawdę, używa jej: through =>: wedding_assignments), a następnie zwraca to. Następnie pytasz szyny, aby ponownie utworzyć te obiekty w swoim wywołaniu do Person.new. Domyślam się, że szyny stają się zdezorientowane, próbując stworzyć obiekt po drugiej stronie a has_many: bez pośredniego obiektu.

byłbym skłonny do restrukturyzacji tego trochę (kod niesprawdzone!):

def new 
    @person = Person.new 
    @wedding = Wedding.new 
    @wedding_assignment = WeddingAssignment.new 
end 

def create 
    @person = Person.new(params[:person]) 
    @wedding = Wedding.new(params[:person]) 
    @assignment = WeddingAssignment.new(params[:wedding_assignment].merge({:person => @person})) 
end 

Mam wrażenie, to będziemy pracować do ostatniej linii. Podejrzewam, aby ta do pracy może trzeba użyć transakcji:

def create 
    @person = Person.new(params[:person]) 
    @wedding = Wedding.new(params[:person]) 
    ActiveRecord::Base.transaction do 
    if @person.valid? && @wedding.valid? 
     [@person,@wedding].each.save! 
     @assignment = WeddingAssignment.new(params[:wedding_assignment].merge({:person => @person})) 
     @assignment.save! 
    end 
    end 
end 

To powinno zapewnić, że wszystko jest tworzone w odpowiedniej kolejności i identyfikatory są dostępne w odpowiednim czasie itp Niestety jednak jest to nieco więcej skomplikowany niż twój przykład, a to oznacza, że ​​będziesz walczył o wsparcie wielu ślubów.

Mam nadzieję, że to pomaga i nie kończy się jako ślepy zaułek.

+0

Zdecydowanie najlepsza odpowiedź. Wykonanie tego w ten sposób oznacza, że ​​nie będę w stanie generować pól formularza w sposób czysty (tj. Jak w: http://railscasts.com/episodes/196-nested-model-form-part-1). Railsy powinny być w stanie zarządzać tymi powiązaniami. Przez weekend ponownie napisałem kod, aby zbudować i uruchomić, zaczynając od modelu łączenia, WeddingAssignment, zamiast Person, i działa dobrze. Więc myślę, że jesteś na dobrej drodze, żeby szyny się gubiły – SooDesuNe

+0

Mam podobny problem, który próbuję rozwiązać przez to pytanie, ale dostaję masowego błędu bezpieczeństwa na osobę. Jakieś pomysły? – ctilley79

Powiązane problemy