Warnung: hier kommt ein kleiner Roman.
Teil 1: die Verbände
Einrichtung Ich würde empfehlen, die Rails guide on associations gründlich, Lesezeichen, um es zu lesen, und lesen Sie es erneut, denn dies ist eine wichtige Sache ist richtig zu verstehen und kann ein bisschen schwierig sein - Es gibt viele Möglichkeiten, wenn Sie über grundlegende Zusammenhänge hinausgehen.
Eine Sache, die Sie über Ihre App bemerken, ist, dass Ihre Benutzer zwei Rollen haben, Käufer und Verkäufer. Sie müssen mit den Namen Ihrer Assoziationen vorsichtig sein - Gibt @user.offers
die Angebote zurück, die der Benutzer hat gemacht, oder die Angebote der Benutzer hat erhalten? Vielleicht möchten Sie in der Lage sein, Listen dieser beiden Dinge in das Profil des Benutzers einzutragen.
Die grundlegenden Beziehungen Sie beschreiben, sind recht einfach:
Ein Benutzer viele Produkte verkaufen können, so User has_many :products
und Product belongs_to :user
Ein Nutzer viele Angebote machen, so User has_many :offers
und Offer belongs_to :user
Ein Produkt kann viele Angebote erhalten, also Product has_many :offers
und Offer belongs_to :product
Das ist alles schön und gut ist, und man konnte sicher nur um dies zu tun bekommen - in dem Fall, dass Sie überspringen nach unten können zu Teil 2 :)
jedoch, sobald Sie die hinzuzufügen starten versuchen through
Beziehungen werden die Gewässer schlammig werden. Immerhin
Offer belongs_to :user
(der Käufer), aber es hat auch einen Benutzer durch Produkt (der Verkäufer)
User has_many :products
(dass sie verkaufen), aber sie haben auch viele Produkte über Angebote (dass sie kaufen - na ja, versuchen zu kaufen).
Aargh, verwirrend!
Dies ist der Punkt, an dem Sie die :class_name
-Option benötigen, mit der Sie eine Assoziation anders als die Klasse, auf die sie verweist, und die :source
-Option benennen können, mit der Sie Assoziationen im 'from' -Modell anders benennen können als 'through Modell.
So können Sie dann Ihre Assoziationen wie folgt bilden:
# 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
Obwohl, wenn Sie Ihre user_id
Spalten seller_id
in der products
Tabelle umbenannt und buyer_id
in der offers
Tabelle, würden Sie nicht brauchen, um diese :foreign_key
Optionen .
Teil 2: Annehmen/Abweisen Angebote
Es gibt eine Reihe von Möglichkeiten, dies zu bewältigen. Ich würde ein boolean Feld accepted
auf Offer
setzen und dann könnte man so etwas wie
# Offer
def accept
self.accepted = true
save
end
def reject
self.accepted = false
save
end
und Sie können die hervorragenden Angebote finden (wo accepted
null ist)
scope :outstanding, where(accepted: nil)
Um die Annahme/Ablehnungs Logik zu erhalten passiert in der Steuerung, könnten Sie adding new RESTful actions betrachten (die verlinkte Anleitung ist eine weitere lesenswerte Sache!). Sie sollten eine Zeile wie
resources :offers
in config/routes.rb finden, die die Standardaktionen index
bietet, show
, edit
, etc. Sie können es zu
ändern
resources :offers do
member do
post :accept
post :reject
end
end
und so etwas wie diese setzen in Ihrem OffersController
def accept
offer = current_user.offers_received.find(params[:id])
offer.accept
end
# similarly for reject
Dann können Sie eine POST-Anforderung an offers/3/accept
ausgeben und es wil l Das Angebot mit der ID 3 wird angenommen. So etwas wie dies in einer Ansicht sollte es tun:
link_to "Accept this offer", accept_offer_path(@offer), method: :post
Bitte beachte, dass ich nicht nur Offer.find(params[:id])
schreiben, weil dann ein schlauer Benutzer Angebote auf dem Namen des Verkäufers akzeptieren könnte. Siehe Rails Best Practices.
Vielen Dank für Ihre Antwort. Ich denke, das funktioniert :) Ich werde die anderen Optionen testen. Noch eine Frage: Wie kann ich das zu meinem Angebotscontroller hinzufügen? Sorry für diese noob Fragen, aber ich lerne immer noch. –
Kein Problem, das ist eine gute Frage! Ich habe meine Antwort aktualisiert, um es zu erklären. –
Ich habe Probleme, diese Migration zu visualisieren. Sollte die Offers-Tabelle nur einen Fremdschlüssel für 'user_id' und' product_id' haben? – sabaeus