Polymorphic association stało się kłopotliwe, problem z integralnościa

Hej,

Mam poszczególne modele

[code=ruby]class Cart
has_many :cart_items
#…
end

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

[code=ruby]def pieces
items.map { |item| item.is_a?(Piece) ? item : item.piece }.uniq
end

pieces.each do |p| p.update_attribute :status, ‘unavailable’ end[/code]

Technicznie jest to ok.

Po prostu refactor IFa na operator trójargumentowy.
Chodziło mi czy nie ma innej drogi poprzez IF niż robienie SELECT’a i UNION w czystym SQL.

Ale dzięki. :wink:

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).