Ostrzeżenie: oto mała powieść.
Część 1: Konfiguracja skojarzeń
polecam czytanie Rails guide on associations dokładnie, zakładka niego i czytać go ponownie, ponieważ jest to kluczowy rzeczą, aby właściwie zrozumieć, a może być nieco kłopotliwe - istnieje wiele opcji, gdy wyjdziesz poza podstawowe skojarzenia.
Jedna rzecz, jaką należy zauważyć, to fakt, że Twoi użytkownicy mają dwie role, kupujących i sprzedających. Musisz być ostrożny z nazwami swoich powiązań - Czy @user.offers
zwraca oferty, które użytkownik ma wykonane, lub oferty użytkownik ma otrzymał? Możesz chcieć umieścić listę obu tych rzeczy w profilu użytkownika.
Podstawowe relacje jesteś opisujące są dość proste:
Użytkownik może sprzedać wiele produktów, więc User has_many :products
i Product belongs_to :user
Użytkownik może dokonać wiele ofert, więc User has_many :offers
i Offer belongs_to :user
Produkt może otrzymać wiele ofert, więc Product has_many :offers
i Offer belongs_to :product
To wszystko dobrze i dobre, i można na pewno dostać się tylko to robi - w takim przypadku można pominąć w dół do części 2 :)
jednak jak najszybciej rozpocząć próby dodania through
relacje wody będą zamulone. Po tym wszystkim,
Offer belongs_to :user
(nabywca), ale ma też użytkownika przez produkt (sprzedający)
User has_many :products
(są one sprzedaży), ale mają również wiele produktów z oferty (że kupują - cóż, próbują kupić).
Aargh, mylące!
Jest to moment, w którym potrzebna jest opcja :class_name
, która pozwala nazwać powiązanie inaczej niż klasa, do której się odnosi, oraz opcję :source
, która pozwala inaczej nazywać asocjacje w modelu 'od' ' Model.
Więc można następnie tworzyć swoje skojarzenia tak:
# User
has_many :products_selling, class_name: 'Product'
has_many :offers_received, class_name: 'Offer',
through: :products_selling, source: :offers
has_many :offers_made, class_name: 'Offer'
has_many :products_buying, class_name: 'Product',
through: :offers_made, source: :product
# Product
belongs_to :seller, class_name: 'User', foreign_key: :user_id
has_many :offers
has_many :buyers, class_name: 'User', through: :offers
# Offer
belongs_to :product
belongs_to :buyer, class_name: 'User', foreign_key: :user_id
has_one :seller, class_name: 'User', through: :product
Chociaż jeśli przemianowany swoje user_id
kolumn do seller_id
w tabeli products
i buyer_id
offers
w tabeli, nie będzie potrzebował tych :foreign_key
opcje .
Część 2: przyjmowanie/odrzucanie ofert
Istnieje wiele sposobów, aby uporać się z tym. Chciałbym umieścić logiczną pole accepted
na Offer
a następnie można mieć coś podobnego
# Offer
def accept
self.accepted = true
save
end
def reject
self.accepted = false
save
end
i można znaleźć znakomite oferty (gdzie accepted
jest null)
scope :outstanding, where(accepted: nil)
Aby uzyskać zaakceptować/odrzucić logikę dzieje się w kontrolerze, możesz wziąć pod uwagę adding new RESTful actions (dołączony przewodnik jest kolejnym wartym przeczytania!). należy znaleźć linię, jak
resources :offers
w config/routes.rb, który stanowi standardowe działania index
, show
, edit
, itd. Można go zmienić na
resources :offers do
member do
post :accept
post :reject
end
end
i umieścić coś takiego w swojej OffersController
def accept
offer = current_user.offers_received.find(params[:id])
offer.accept
end
# similarly for reject
Następnie można wysłać żądanie POST do offers/3/accept
i Wil l proponuję przyjęcie oferty o identyfikatorze 3. Coś takiego w widoku powinien to zrobić:
link_to "Accept this offer", accept_offer_path(@offer), method: :post
pamiętać, że nie tylko pisać Offer.find(params[:id])
bo wtedy przebiegły użytkownik może akceptować ofert w imieniu sprzedawcy. Zobacz Rails Best Practices.
Dziękuję za odpowiedź. Myślę, że to działa :) Będę testować inne opcje. Jeszcze jedno pytanie: Jak mogę dodać to do kontrolera moich ofert? Przepraszam za te pytania, ale wciąż się uczę. –
Nie ma problemu, to dobre pytanie! Zaktualizowałem swoją odpowiedź, aby to wyjaśnić. –
Mam problem z wizualizacją tej migracji. Czy tabela Oferty powinna mieć klucz obcy dla "id_użytkownika" i "identyfikator_produktu"? – sabaeus