2013-02-14 6 views
22

Używam build, fields_for i accepts_nested_attributes_for do tworzenia nowej notatki rejestracyjnej w tym samym formularzu, co nowa rejestracja (zawiera wiele not rejestracyjnych). Wspaniały.Jak uzyskać kompilację Railsów i fields_for, aby utworzyć tylko nowy rekord i nie uwzględniać istniejącego?

Problem: W formularzu edycji istniejącej rejestracji chcę utworzyć kolejną nową notatkę rejestracyjną, ale nie chcę widzieć pola dla każdego z istniejących dokumentów rejestracyjnych.

mam to

class Registration < ActiveRecord::Base 
    attr_accessible :foo, :bar, :registration_notes_attributes 
    has_many :registration_notes 
    accepts_nested_attributes_for :registration_notes 
end 

i to

class RegistrationsController < ApplicationController 
    def edit 
    @registration = Registration.find(params[:id]) 
    @registration.registration_notes.build 
    end 
end 

iw widoku Robię to:

<%= form_for @registration do |r| %> 
    <%= r.text_field :foo %> 
    <%= r.text_field :bar %> 
    <%= r.fields_for :registration_notes do |n| %> 
    <%= n.text_area :content %> 
    <% end %> 
<% end %> 

i tworzy pusty obszar tekstu na nowy dowód rejestracyjny (dobry) i każdy istniejący dowód rejestracyjny dla przy rejestracji (nie, dziękuję).

Czy istnieje sposób na utworzenie nowej notatki dla tej rejestracji i pozostawienie istniejących tylko w spokoju?

Odpowiedz

62

EDIT: Moje poprzednie odpowiedź (patrz niżej) podsłuch mnie, bo to nie jest bardzo miłe (nadal pętle przez wszystkich innych registration_notes niepotrzebnie). Po przeczytaniu API nieco więcej, najlepszym sposobem, aby uzyskać zachowanie PO chciała ma zastąpić:

<%= r.fields_for :registration_notes do |n| %> 

z:

<%= r.fields_for :registration_notes, @registration.registration_notes.build do |n| %> 

fields_for opcjonalnie trwa drugi parametr, który jest specyficzny obiekt do przechodzą do konstruktora (see the API), który jest wbudowany. Prawdopodobnie lepiej jest utworzyć i przekazać nową notatkę w kontrolerze zamiast w formie (tylko po to, aby przenieść logikę z widoku).


Original odpowiedź (byłem tak blisko):

Właśnie w celu wyjaśnienia, chcesz swoją postać edycja zawierać nową notatkę zagnieżdżona rejestracyjny (i zignorować wszelkie inne istniejące)? Nie testowałem tego, ale powinieneś być w stanie to zrobić poprzez zastąpienie:

<%= r.fields_for :registration_notes do |n| %> 

z:

<%= r.fields_for @registration.registration_notes.build do |n| %> 

EDIT: Dobra, od szybkiego testu własną rękę, że nie robi” t pracy, ale zamiast tego można zrobić:

<%= r.fields_for :registration_notes do |n| %> 
    <%= n.text_area :content if n.object.id.nil? %> 
<% end %> 

Spowoduje to dodanie tylko obszar tekstowy jeśli identyfikator noty rejestracyjnej jest zerowa (to znaczy nie został jeszcze zapisany.).

Również ja faktycznie testowany ten pierwszy i to działa;)

+0

wierzę chce utworzyć nową rejestrację _note', który należy do obiektu '@ registration'. – Huy

+0

Moje zrozumienie polegało na tym, że chce dołączyć notatkę dołączoną do edycji, więc formularz przetwarza zmiany do rejestracji, a także tworzy nową notatkę rejestracyjną, umożliwiającą użytkownikowi pozostawienie powiązanych komentarzy lub tym podobnych. W takim przypadku oddzielny formularz dla notatki nie działałby, czy byłby (jak musiałby być składany osobno)? –

+0

Ahhh, może tego właśnie chce. :) – Huy

1

Jeśli chcesz utworzyć nowy formularz rejestracji w akcji edycji, możesz po prostu utworzyć instancję nowego obiektu registration_note. W tej chwili twój formularz dotyczy istniejącego obiektu rejestracyjnego.

Wierzę, że to jest to, co chcesz:

class RegistrationsController < ApplicationController 
    def edit 
    @new_registration_note = RegistrationNote.new 
    @registration = Registration.find(params[:id]) 
    @registration.registration_notes.build 
    end 
end 

Państwa zdaniem, należy przekazać ukrytą param która odwołuje się do ID rekordu rejestracji:

<%= form_for @new_registration_note do |r| %> 
    <%= r.hidden_field :registration_id, :value => @registration.id %> 
    <%= r.text_area :content %> 
<% end %> 

Teraz można tworzyć nowe notatka rejestracyjna, że ​​należy do@registration. Upewnij się, że kolumna w tabeli registration_notes wskazuje na rejestrację. Możesz przeczytać więcej o stowarzyszeniach tutaj: http://guides.rubyonrails.org/association_basics.html

1

Dziękuję bardzo za pomoc, jak powiedziałem w moim poście tylko problem z podejściem z „Zaid Crouch” (nie wiem wiedzieć, jak zrobić odniesienie do użytkownika hehe) jest to, że jeśli formularz zawiera pola błędów, formularz będzie jasny i bum po ponownym załadowaniu strony nie będziesz miał nic wypełnionego w formularzu i możesz sobie wyobrazić, jeśli masz formularz 20 lub 30 pól, które byłyby straszne doświadczenie użytkownik oczywiście

Oto moje rozwiązanie, które działa z modelami walidacji:

class Registration < ActiveRecord::Base 
    attr_accessible :foo, :bar, :registration_notes_attributes 
    has_many :registration_notes 
    has_one :new_registration, class_name: 'RegistrationNote' 
    accepts_nested_attributes_for :new_registration 
end 

class RegistrationsController < ApplicationController 
    def edit 
    @registration = Registration.find(params[:id]) 
    @registration.build_new_registration 
    end 
end 

<%= form_for @registration do |r| %> 
    <%= r.text_field :foo %> 
    <%= r.text_field :bar %> 
    <%= r.fields_for :new_registration do |n| %> 
    <%= n.text_area :content %> 
    <% end %> 
<% end %> 

Używam simple_form w moim przykładzie, jeśli chcesz zobaczyć to samo pracy z walidacji i transakcji przyjrzeć kompletnego post tutaj: http://elh.mx/ruby/using-simple_form-for-nested-attributes-models-in-a-has_many-relation-for-only-new-records/

0

Heriberto Perez Jak słusznie wskazał rozwiązanie w najbardziej upvoted odpowiedź po prostu odrzuci wszystko, jeśli wystąpi błąd sprawdzania poprawności na jednym z pól.

Moje podejście jest podobne do Heriberto tych, ale mimo to nieco inaczej:

Model:

class Registration < ActiveRecord::Base 
    has_many :registration_notes 
    accepts_nested_attributes_for :registration_notes 

    # Because 0 is never 1 this association will never return any records. 
    # Above all this association don't return any existing persisted records. 
    has_many :new_registration_notes, -> { where('0 = 1') } 
            , class_name: 'RegistrationNote' 
    accepts_nested_attributes_for :new_registration_notes 
end 

Kontroler:

class RegistrationsController < ApplicationController 
    before_action :set_registration 

    def edit   
    @registration.new_registration_notes.build 
    end 

    private 

    def set_registration 
    @registration = Registration.find(params[:id]) 
    end 

    def new_registration_params 
    params.require(:registration).permit(new_registrations_attributes: [:content]) 
    end 
end 

Widok:

<%= form_for @registration do |r| %> 
    <%= r.text_field :foo %> 
    <%= r.text_field :bar %> 
    <%= r.fields_for :new_registration_notes do |n| %> 
    <%= n.text_area :content %> 
    <% end %> 
<% end %> 
Powiązane problemy