2012-01-08 8 views
6

Mam zasób Item i zasoby właściciela.Jak utworzyć nowy obiekt, odwołując się do istniejącego zagnieżdżonego atrybutu?

rails g scaffold Item name:string 
rails g scaffold Owner name:string 

class Item < ActiveRecord::Base 
    has_one :owner 
    accepts_nested_attributes_for :owner 
end 

class Owner < ActiveRecord::Base 
    belongs_to :item 
end 

Mój problem polega na tym, że nie mogę utworzyć nowego obiektu Item odwołującego się do istniejącego obiektu właściciela.

In /db/migrate/create_owners.rb 
def self.up 
    ... 
    t.integer :item_id 
end 

rake db:migrate 
rails c 

ruby-1.9.2-p0 > o= Owner.create(:name => "Test") 
=> #<Owner id: 1, name: "Test", created_at: "...", updated_at: "..."> 

ruby-1.9.2-p0 > i= Item.create(:owner_attributes => {"id" => Owner.last.id.to_s}) 
ActiveRecord::RecordNotFound: Couldn't find Owner with ID=1 for Item with ID= 

Jestem świadomy, że Item.create(:owner_id => "1") będzie działać w tym przypadku, ale niestety to nie jest dobrym rozwiązaniem w mojej aplikacji. Jest tak dlatego, że dodajemy i usuwam zagnieżdżone atrybuty w locie i na przykład trzeba utworzyć nowy obiekt Item z jednym istniejącym właścicielem obiektu i jednym nowym obiektem właściciela.

znalazłem te linki, ale nie może działać, jeśli jest to cecha lub błąd w szynach:
https://rails.lighthouseapp.com/projects/8994/tickets/4254-assigning-nested-attributes-fails-for-new-object-when-id-is-specified
http://osdir.com/ml/RubyonRails:Core/2011-05/msg00001.html

Czy ktoś mógłby dać mi pomysł, w jaki sposób dokonać tej pracy lub czy źle zrozumiałem prawidłowy sposób używania "accepts_nested_attributes_for" ??

Używam Rails 3.0.5 i Ruby 1.9.2p0.

Z góry dziękuję.

Odpowiedz

1

Podczas próby utworzenia Item z identyfikatorem właściciela w zagnieżdżonych atrybutów, mówi ActiveRecord zaktualizować istniejący Owner rekord. ActiveRecord nie może odnaleźć rekordu Owner, ponieważ nie istnieje żadna istniejąca wartość klucza obcego (id dla rekordu pozycji jest nadal zerowy).

Item.create(:owner_attributes => {"id" => Owner.last.id.to_s}) 
#=> ActiveRecord::RecordNotFound: Couldn't find Owner with ID=1 for Item with ID= 

Spróbuj wymienić przypisania has_one/belongs_to i przenieść klucz obcy do tabeli elementów. Następnie możesz ustawić klucz obcy w modelu macierzystym (niezagnieżdżonym) i nadal używać zagnieżdżonych atrybutów.

class Item < ActiveRecord::Base 
    belongs_to :owner 
    accepts_nested_attributes_for :owner 
end 

class Owner < ActiveRecord::Base 
    has_one :item 
end 

owner = Owner.create 

Item.create(:owner_id => owner.id, :owner_attributes => {"id" => owner.id, ...}) 
#=> Works!!! Note that the owner id is used twice. With some work you could probably set the id in one place or the other. 
+0

Dzięki! Nie pracowałem nad tym projektem od ponad roku, ale twoja odpowiedź ma sens. Wypróbuję to (bez zainteresowania), kiedy będę miał chwilę. –

0

accepts_nested_attributes_for jest używany tylko dla stowarzyszeń has_one i has_many. (patrz http://api.rubyonrails.org/classes/ActiveRecord/NestedAttributes/ClassMethods.html no belongs_to) Nazywa się "zagnieżdżony", więc niewiele tam pomoże. Być może chcesz zmienić swoją aplikację?

W szczególności przypadek wystąpienia błędu polega na tym, że rodzic powinien być w stanie znaleźć model zagnieżdżony, biorąc pod uwagę identyfikator modelu zagnieżdżonego. To znaczy.

parent.nested_model.find(id) 

To nie wydaje się, w zasadzie, aby zatrzymać z aktualizacją modeli podrzędne, które nie należą do rodzica

+0

Dzięki. Zmieniłem przykład użycia has_one. Niestety problem nadal występuje. Czy jest jakiś sposób, aby osiągnąć to, co próbuję, lub najlepiej, gdy wracam do deski kreślarskiej? –

+0

Nie prawda, będzie działać dla belongs_to, tam po prostu jej nie ma. Jeśli działa has_one, funkcja belongs_to również zadziała. –

+0

@RyanBigg hmm, musiałem źle przeczytać, jak działa zagnieżdżanie. tak 'należy_to' powinno działać, jeśli has_one działa. @Jack nie wygląda na to, że to problem, ponieważ link do latarni morskiej (https://rails.lighthouseapp.com/projects/8994/tickets/4254-assigning-nested-attributes-fails-for-new-object-when-id- jest określony # ticket-4254-6), który opublikowałeś. –

2

I rozwiązać problem w inny sposób i chciał odpowiedzieć uproszczoną wersję nim tutaj w przypadku pomaga każdemu. W mojej prawdziwej aplikacji assosciation między obydwoma zasobami jest HABTM, a zasób zagnieżdżony to załącznik do pliku.

Tak więc w akcji tworzenia kontrolera oddzielaję parametry dla oryginalnego zasobu i dla zasobu zagnieżdżonego.

Następnie dalej dzielę zagnieżdżony zasób na obiekty istniejące w bazie danych i obiekty, które tego nie robią, umieszczając identyfikatory tych, które robią w tablicy.

Jeśli nie ma żadnych zagnieżdżonych obiektów, oznacza to, że płyną stąd.

Jednak zakładając, zarówno istniejących i nowych obiektów zagnieżdżonych są obecne, utworzyć nowy obiekt Item tak:
@item = Item.new(:attachment_ids => existing_attachment_ids)

Potem zaktualizuj @item tak:
@item.update_attributes(original_item_params)
@item.update_attributes(params_for_new_nested_objects)

Następnie można wywołać @item.save i ponownie renderuj widok, jeśli wystąpią jakiekolwiek błędy.

Nadal nie mogę pracować, jeśli jest to błąd lub funkcja ir Rails.Jeśli ktoś ma jakiekolwiek przemyślenia na ten temat lub moje rozwiązanie, byłbym bardzo zadowolony z ich wysłuchania.

+0

Po prostu FYI, zobacz także ten stary bilet Railsowy: https://rails.lighthouseapp.com/projects/8994/tickets/4254-przypomina-ne-na-przypadkach-wprowadzonych-obiektach-when-id-jest-określonych –

Powiązane problemy