Ale*_*ara 5 ruby ruby-on-rails relationship belongs-to
我有三个模型:用户,产品,优惠以及这些模型之间关系的问题.
场景:
用户1发布产品
用户2可以向用户1发送价格为10美元的报价
用户1可以接受或拒绝该优惠
我现在的问题是:
用户,产品和优惠之间的正确关系是什么?
我该如何处理这些"接受或拒绝"的行为?
可能有更好的解决方案吗?
用户模型:
class User < ActiveRecord::Base
attr_accessible :name, :email, :password, :password_confirmation, :remember_me, :avatar, :screen_name
has_many :products
has_many :offers,:through => :products
end
Run Code Online (Sandbox Code Playgroud)
产品型号:
class Product < ActiveRecord::Base
attr_accessible :content, :price, :title, :tag_list, :productimage, :user_id
belongs_to :user
has_many :offers, :through => :users
end
Run Code Online (Sandbox Code Playgroud)
优惠型号:
class Offer < ActiveRecord::Base
attr_accessible :offer_price, :status, :user_id, :product_id
has_many :products
has_many :users, through: :products
end
Run Code Online (Sandbox Code Playgroud)
提前致谢 :)
编辑:
我正在使用Rails 3.2.8
警告:这是一本小小说.
第1部分:建立关联
我建议彻底阅读关于关联的Rails指南,给它添加书签,然后重新阅读,因为这是正确理解的关键,并且可能有点棘手 - 一旦超出基本关联,有很多选项.
关于您的应用,需要注意的一点是,您的用户有两个角色,买家和卖家.你将需要小心你的协会的名称-不@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关系,水就会变得混乱.毕竟,
Offer belongs_to :user (买方),但它也有用户通过产品(卖方)
User has_many :products (他们正在销售),但他们也有许多产品通过报价(他们正在购买 - 好吧,试图购买).
Aargh,令人困惑!
当您需要该: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
Run Code Online (Sandbox Code Playgroud)
但如果你重新命名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
Run Code Online (Sandbox Code Playgroud)
你可以找到优秀的报价(哪里accepted是null)
scope :outstanding, where(accepted: nil)
Run Code Online (Sandbox Code Playgroud)
要在控制器中发生接受/拒绝逻辑,您可以考虑添加新的RESTful操作(链接指南是另一个值得仔细阅读的指南!).你应该找到像这样的一行
resources :offers
Run Code Online (Sandbox Code Playgroud)
在配置/ routes.rb中,它提供了标准的动作index,show,edit,等,您可以将其更改为
resources :offers do
member do
post :accept
post :reject
end
end
Run Code Online (Sandbox Code Playgroud)
并把这样的东西放在你的 OffersController
def accept
offer = current_user.offers_received.find(params[:id])
offer.accept
end
# similarly for reject
Run Code Online (Sandbox Code Playgroud)
然后,您可以发出POST请求offers/3/accept,这将导致接受ID为3的商品.视图中的这样的东西应该这样做:
link_to "Accept this offer", accept_offer_path(@offer), method: :post
Run Code Online (Sandbox Code Playgroud)
请注意,我不只是写,Offer.find(params[:id])因为一个狡猾的用户可以代表卖家接受报价.请参阅Rails最佳实践.
| 归档时间: |
|
| 查看次数: |
1368 次 |
| 最近记录: |