Problem z create

Witam.

Mam:

  • model Document :id, :number: … inne pola
  • model Hardware :id, :name: :serial :document_in_id :document_out_id.

Jest to standardowe document has_many :hardwares.

Za pomocą formularza dodaje dokument + dwa urządzenia na tym dokumencie.

Zgodnie z tym że w modelu Document mam:
has_many :hardwares, :foreign_key => ‘document_in_id’
to w hardwares wypełnia mi się automatycznie document_in_id.

Czyli działa wszytko OK zgodnie z railscast 73.

Teraz chciałbym dodać nowy dokument , nowy numer, nowe inne pola, ale na formularzu dodaje teraz urządzenia które są już w bazie. I w takim przypadku zamiast dodać nowy rekord z tymi urządzeniami, chciałbym uzupełnić :document_out_id - id nowego dokumentu w urządzeniu któe juz jest.

Obrazek :slight_smile:

Document (1, ‘Numer_1’, ‘Cos1’, ‘Cos2’)
Hardware(1, ‘Name_1’, ‘ZXC123’, 1)
Hardware(2, ‘Name_2’, ‘HGH765’, 1)

Baza po tym dodaniu:

DOCUMENTS
id | number | Pole_X | Pole_Y

1 | Numer_1 | Cos1 | Cos_2

HARDWARES
id | name | serial | doc_in_id | doc_out_id

1 | Name_1| ZXC123 | 1 | NULL
1 | Name_2| HGH765 | 1 | NULL

Teraz dodaje dokument z jednym nowym urządzeniem:
Document (2, ‘Numer_2’, ‘Cos3’, ‘Cos4’)
Hardware(3, ‘Name_3’, KJI988’, 2)

Baza po tym dodaniu:

DOCUMENTS
id | number | Pole_X | Pole_Y

1 | Numer_1 | Cos1 | Cos_2
2 | Numer_2 | Cos3 | Cos_4

HARDWARES
id | name | serial | doc_in_id | doc_out_id

1 | Name_1| ZXC123 | 1 | NULL
1 | Name_2| HGH765 | 1 | NULL
1 | Name_3| KJI988 | 2 | NULL

A teraz dodaje urządzenie któe jest juz w bazie!

Document (3, ‘Numer_3’, ‘Cos5’, ‘Cos6’)
Hardware(3, ‘Name_3’, KJI988’, 2)

Baza po tym dodaniu:

DOCUMENTS
id | number | Pole_X | Pole_Y

1 | Numer_1 | Cos1 | Cos_2
2 | Numer_2 | Cos3 | Cos_4
3 | Numer_2 | Cos5 | Cos_6

HARDWARES
id | name | serial | doc_in_id | doc_out_id

1 | Name_1| ZXC123 | 1 | NULL
1 | Name_2| HGH765 | 1 | NULL
1 | Name_3| KJI988 | 2 | 3 <------- nie powstał nowy rekord tylko uzupełniło stary id

Wiem, że długie i w ogóle. Mam nadzieję że dość jasno opisałem a jak nie opisałem to narysowałem :).
Nie wiem jak kazać raz wypełnić doc_in_od a innym razem doc_out_id.
Może ktoś coś podpowiedzieć jak to zrealizować najlepiej?
Chodzi o to żeby wyciągnąć info o sprzęcie który jest na stanie i o takim który na stanie był.
Jest ten, który ma wypełnione tylko doc_in_id a doc_out_id ma NULL. A był ten, co ma wypełnione oba pola. doc_in_id i doc_out_id.

Pozdrawiam
Sebastian

Zamiast jednej relacji zdefiniuj dwie:

[code=ruby]class Document < ActiveRecord::Base

has_many :current_hardwares, :class_name => ‘CurrentHardware’, :foreign_key => :document_in_id
has_many :past_hardwares, :class_name => ‘PastHardware’, :foreign_key => :document_out_id

end

class Hardware < ActiveRecord::Base

def move_to_past!
unless self.document_in_id.nil?
self.document_out_id = self.document_in_id
self.document_in_id = nil
save
end
end

end

class CurrentHardware < Hardware

belongs_to :document, :foreign_key => :document_in_id

end

class PastHardware < Hardware
belongs_to :document, :foreign_key => :document_out_id
end[/code]
Możesz asocjacje nazwać bardziej odpowiednio jeśli chcesz. Hardware twórz zawsze “idąc przez” document, np.

@document = Document.find :first @document.current_hardwares.create(:serial_no => '123') # etc
Jeśli chcesz przesunąć dany hardware z current do past to wywołaj

ch = @document.current_hardwares.first ch.move_to_past!
ale pamiętaj że powyższa implementacja nie zmieni automatycznie typu klasy z CurrentHardware na PastHarddware - jeśli polegasz na tym to musisz ją zmienić.

To ogólny zarys pisany “z biegu” aby pokazać rozwiązanie z użyciem dziedziczenia niż konkretna działająca implementacja.