class CartItem
belongs_to :purchasable, :polymorphic => true
belongs_to :cart
#…
end
class Piece
has_many :cart_items, as: :purchasable
#…
end
class Offer
belongs_to :piece
#…
end[/code]
Jeśli mam w koszyku (Cart) dodane pare ofert (Offer) oraz parę dzieł (Piece) to podczas kupowania MUSZĘ oznaczyć dzieła jak niedostępne.
Czy da się jakoś zgrabnie zaaktualizować wszystkie Piece’y (nawet to które “przechodzą” przez Offer) nie rozbijając tego na brzydkie IF’y? Coś ala:
cart = Cart.find(x)
cart.items.each |item|
if item.is_a? Piece
item.purchasable.update_column(:status, "unavailable")
else # Offer
item.purchasable.piece.update_column(:status, "unavailable")
end
end
MSZ, istotniejszą częścią tego refactoru jest fakt zdefiniowania kolekcji pieces w instancji Cart i operowanie na niej w kontrolerze, zamiast imperatywnego grzebania w kolekcji items, która jest szczegółem implementacyjnym.
EDIT:
Kod taki jest łatwiejszy do testowania. Poza tym, na początek możesz definicję kolekcji pieces zostawić w Rubiowej postaci. Kiedy uznasz, że nie jest to wystarczające, możesz spokojnie przedefiniować ją (na przykład wklepać jakiegoś SQLa), nie zmieniając kodu wykonującego dany scenariusz (w tym wypadku zakup).