警告: ここに小さな小説があります。
パート 1: 関連付けの設定
関連付けに関する Rails ガイドをよく読み、ブックマークして、もう一度読むことをお勧めします。これは、適切に理解するための重要な事項であり、少しトリッキーになる可能性があるためです。基本的な関連付けを超えると、多くのオプションがあります。
このアプリについて注意すべきことの 1 つは、ユーザーには買い手と売り手の 2 つの役割があることです。関連付けの名前には注意が必要です。ユーザーが行ったオファーまたはユーザーが受け取っ@user.offers
たオファーを返しますか? これら両方のリストをユーザーのプロファイルに入れたいと思うかもしれません。
あなたが説明している基本的な関係はかなり単純です。
ユーザーは多くの製品を販売できるためUser has_many :products
、Product belongs_to :user
ユーザーは多くのオファーを行うことができるためUser has_many :offers
、Offer belongs_to :user
商品には多くのオファーが寄せられる場合がありますProduct has_many :offers
。Offer belongs_to :product
それはすべてうまくいっています。これを行うだけで確かに取得できます-その場合、パート2にスキップできます:)
ただし、関係を追加しようとするとすぐにthrough
、水が濁ってきます。結局、
ああ、紛らわしい!
これは、:class_name
関連付けが参照するクラスとは異なる:source
名前を関連付けに付けることができるオプションと、「from」モデルの関連付けに「through」モデルとは異なる名前を付けることができるオプションが必要な場合です。
したがって、次のように関連付けを作成できます。
# 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
ただし、テーブル内およびテーブル内でuser_id
列の名前を に変更した場合、これらのオプションは必要ありません。seller_id
products
buyer_id
offers
:foreign_key
パート 2: オファーを受け入れる/拒否する
これに対処する方法はいくつかあります。ブール値フィールドaccepted
を配置するOffer
と、次のようなものを持つことができます
# Offer
def accept
self.accepted = true
save
end
def reject
self.accepted = false
save
end
そして、あなたは未解決のオファーを見つけることができます(どこaccepted
がnullです)
scope :outstanding, where(accepted: nil)
コントローラーで承認/拒否ロジックを実行するには、新しい RESTful アクションを追加することを検討してください (リンクされたガイドも、よく読む価値があります!)。次のような行が見つかるはずです
resources :offers
config/routes.rb で、標準アクションindex
、show
、edit
などを提供します。これを次のように変更できます。
resources :offers do
member do
post :accept
post :reject
end
end
このようなものをあなたのOffersController
def accept
offer = current_user.offers_received.find(params[:id])
offer.accept
end
# similarly for reject
次に、POST リクエストを発行するoffers/3/accept
と、ID 3 のオファーが受け入れられます。ビューでこのようなことを行う必要があります。
link_to "Accept this offer", accept_offer_path(@offer), method: :post
Offer.find(params[:id])
悪意のあるユーザーが売り手に代わってオファーを受け入れる可能性があるため、私が書いただけではないことに注意してください. Rails のベスト プラクティスを参照してください。