Cảnh báo: ở đây có một cuốn tiểu thuyết nhỏ.
Phần 1: thành lập các hiệp hội
tôi khuyên bạn nên đọc Rails guide on associations kỹ lưỡng, đánh dấu nó, và đọc nó một lần nữa, bởi vì đây là một điều quan trọng để hiểu đúng, và có thể là một chút khôn lanh - có rất nhiều tùy chọn khi bạn vượt ra ngoài các liên kết cơ bản.
Một điều cần lưu ý về ứng dụng của bạn là người dùng của bạn có hai vai trò, người mua và người bán. Bạn sẽ cần phải cẩn thận với tên của các hiệp hội của bạn - Không @user.offers
trả lại phiếu mua hàng mà người dùng có được thực hiện hoặc phiếu mua hàng mà người dùng có đã nhận được? Bạn có thể muốn đặt danh sách cả hai thứ này vào hồ sơ của người dùng.
Các mối quan hệ cơ bản bạn đang mô tả là khá đơn giản:
Một người sử dụng có thể bán nhiều sản phẩm, vì vậy User has_many :products
và Product belongs_to :user
Một người sử dụng có thể làm cho nhiều lời đề nghị, vì vậy User has_many :offers
và Offer belongs_to :user
Sản phẩm có thể nhận được nhiều phiếu mua hàng như vậy Product has_many :offers
và Offer belongs_to :product
Đó là tất cả tốt và tốt, và bạn chắc chắn có thể nhận được bằng cách chỉ làm điều này - trong trường hợp này bạn có thể bỏ xuống Phần 2 :)
Tuy nhiên, ngay sau khi bạn bắt đầu cố gắng thêm through
mối quan hệ các vùng biển sẽ nhận được bùn. Sau khi tất cả,
Offer belongs_to :user
(người mua), nhưng nó cũng có một người dùng thông qua sản phẩm (người bán)
User has_many :products
(mà họ đang bán), nhưng họ cũng có nhiều sản phẩm thông qua cung cấp (mà họ đang mua - tốt, cố gắng mua).
Aargh, khó hiểu!
Đây là điểm khi bạn cần tùy chọn :class_name
, cho phép bạn đặt tên một liên kết khác với lớp mà nó đề cập và tùy chọn :source
, cho phép bạn đặt tên cho các liên kết trên mô hình 'từ' khác nhau ' mô hình.
Vì vậy, bạn sau đó có thể hình thành các hiệp hội của bạn như thế này:
# 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
Mặc dù nếu bạn đã đổi tên user_id
cột của bạn để seller_id
trong bảng products
, và buyer_id
trong bảng offers
, bạn sẽ không cần những :foreign_key
tùy chọn .
Phần 2: chấp nhận/từ chối cung cấp
Có một số cách để giải quyết vấn đề này. Tôi sẽ đặt một lĩnh vực boolean accepted
trên Offer
và sau đó bạn có thể có một cái gì đó giống như
# Offer
def accept
self.accepted = true
save
end
def reject
self.accepted = false
save
end
và bạn có thể tìm thấy những cung cấp vượt trội (nơi accepted
là null)
scope :outstanding, where(accepted: nil)
Để có được chấp nhận/từ chối Logic xảy ra trong bộ điều khiển, bạn có thể xem xét adding new RESTful actions (hướng dẫn được liên kết là một hướng dẫn khác đáng đọc kỹ!). Bạn nên tìm một dòng như
resources :offers
trong config/routes.rb, cung cấp các hoạt động tiêu chuẩn index
, show
, edit
, vv Bạn có thể thay đổi nó để
resources :offers do
member do
post :accept
post :reject
end
end
và đặt một cái gì đó như thế này trong bạn OffersController
def accept
offer = current_user.offers_received.find(params[:id])
offer.accept
end
# similarly for reject
Sau đó, bạn có thể đưa ra một yêu cầu POST để offers/3/accept
và nó wil l làm cho phiếu mua hàng có id 3 được chấp nhận. Một cái gì đó như thế này trong một cái nhìn nên làm điều đó:
link_to "Accept this offer", accept_offer_path(@offer), method: :post
Lưu ý rằng tôi không chỉ viết Offer.find(params[:id])
vì sau đó người dùng xảo quyệt có thể chấp nhận cung cấp trên thay mặt cho người bán. Xem Rails Best Practices.
Cảm ơn bạn đã trả lời. Tôi nghĩ rằng công trình này :) Tôi sẽ kiểm tra các tùy chọn khác. Một câu hỏi nữa: Làm thế nào tôi có thể thêm điều này vào bộ điều khiển phiếu mua hàng của tôi? Xin lỗi vì những câu hỏi noob nhưng tôi vẫn đang học. –
Không sao cả, đó là một câu hỏi hay! Tôi đã cập nhật câu trả lời của mình để giải thích. –
Tôi đang gặp sự cố khi trực quan hóa việc di chuyển này. Bảng phiếu mua hàng chỉ có khóa ngoại cho 'user_id' và' product_id'? – sabaeus