Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails 2个用户之间的产品订单_Ruby On Rails_Ruby_Relationship_Belongs To - Fatal编程技术网

Ruby on rails 2个用户之间的产品订单

Ruby on rails 2个用户之间的产品订单,ruby-on-rails,ruby,relationship,belongs-to,Ruby On Rails,Ruby,Relationship,Belongs To,我有三个模型:用户模型、产品模型、报价模型和这些模型之间的关系问题 场景: 用户1发布一个产品 用户2可以向用户1发送价格为10美元的报价 用户1可以接受或拒绝报价 我现在的问题是: 用户、产品和服务之间的正确关系是什么 我如何处理这些“接受或拒绝”操作 有没有更好的解决办法 用户模型: class User < ActiveRecord::Base attr_accessible :name, :email, :password, :password_confirmation,

我有三个模型:用户模型、产品模型、报价模型和这些模型之间的关系问题

场景:

用户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
class用户:产品
结束
产品型号:

class Product < ActiveRecord::Base
    attr_accessible :content, :price, :title, :tag_list, :productimage, :user_id
    belongs_to :user
    has_many :offers, :through => :users
end
类产品:用户
结束
报价模式:

class Offer < ActiveRecord::Base
    attr_accessible :offer_price, :status, :user_id, :product_id
    has_many :products
    has_many :users, through: :products
end
class Offer
提前感谢:)

编辑:

我使用的是Rails 3.2.8,怎么样

class User < ActiveRecord::Base
  has_many :products  # All products posted by this user
  has_many :offers    # All offers created by this user
end

class Product < ActiveRecord::Base
  belongs_to :user   # This is the user who posts the product (User 1)
  has_many :offers
end

class Offer < ActiveRecord::Base
  belongs_to :product
  belongs_to :user   # This is the user who creates the offer (User 2)

  # Use a 'state' field with values 'nil', 'accepted', 'rejected' 
end 

您可以根据自己的需要对此进行改进,例如,如果不同的用户可以发布相同的产品。

除了关系之外,您的模型已经足够好了。当您试图区分拥有的产品与感兴趣的产品(提供的产品)以及产品所有者与感兴趣的用户(提供产品的用户)时,就会出现混淆。如果你能想出一个更好的命名约定,你可以很容易地修复它

1。改善关系

class User < ActiveRecord::Base
  attr_accessible :name, :email, :password, :password_confirmation, :remember_me, :avatar, :screen_name
  has_many :owned_products, :class_name => "Product"
  has_many :offers 
  has_many :interested_products, :through => :offers
end

class Offer < ActiveRecord::Base
  attr_accessible :offer_price, :status, :user_id, :product_id
  belongs_to :interested_user, :class_name => "User", :foreign_key => :user_id
  belongs_to :interested_product, :class_name => "Product", :foreign_key => :product_id
end

class Product < ActiveRecord::Base
  attr_accessible :content, :price, :title, :tag_list, :productimage, :user_id
  belongs_to :owner, :foreign_key => :user_id, :class_name => "User"
  has_many :offers 
  has_many :interested_users, :through => :offers
end
2。处理接受和拒绝操作。

从您的描述中,我看到对报价有两种可能的状态更改,“创建”->“接受”或“创建”->“拒绝”。我建议你看看。状态机将通过其助手方法为您的模型添加很好的风格,我认为这在您的案例中非常有用。因此,您的
报价
型号将如下所示

class Offer < ActiveRecord::Base
  # attr_accessible :title, :body
  attr_accessible :offer_price, :status, :user_id, :product_id
  belongs_to :interested_user, :class_name => "User", :foreign_key => :user_id
  belongs_to :interested_product, :class_name => "Product", :foreign_key => :product_id

  state_machine :status, :initial => :created do
    event :accept do
      transition :created => :accepted
    end
    event :reject do
      transition :created => :reject
    end
  end
end

#cool helper methods
@offer = Offer.new
@offer.accepted? #returns false
@offer.reject #rejects the offer
@offer.rejected? #returns true
class Offer“用户”,:外键=>:用户id
属于:感兴趣的产品,:类名称=>“产品”,:外键=>:产品id
状态机器:状态,:初始=>:已创建do
事件:接受do
转换:已创建=>:已接受
结束
事件:拒绝do
转换:已创建=>:拒绝
结束
结束
结束
#酷助手方法
@offer=offer.new
@报价,接受吗#返回false
@拒绝接受提议
@拒绝#返回true

我希望这能给你一个更好的画面。

警告:这是一本小小说

第1部分:建立协会

class User < ActiveRecord::Base
  attr_accessible :name, :email, :password, :password_confirmation, :remember_me, :avatar, :screen_name
  has_many :owned_products, :class_name => "Product"
  has_many :offers 
  has_many :interested_products, :through => :offers
end

class Offer < ActiveRecord::Base
  attr_accessible :offer_price, :status, :user_id, :product_id
  belongs_to :interested_user, :class_name => "User", :foreign_key => :user_id
  belongs_to :interested_product, :class_name => "Product", :foreign_key => :product_id
end

class Product < ActiveRecord::Base
  attr_accessible :content, :price, :title, :tag_list, :productimage, :user_id
  belongs_to :owner, :foreign_key => :user_id, :class_name => "User"
  has_many :offers 
  has_many :interested_users, :through => :offers
end
我建议你仔细阅读,把它标上书签,然后再读一遍,因为这是正确理解的关键,而且可能有点棘手——一旦你超越了基本的关联,就有很多选择

关于你的应用程序,需要注意的一点是,你的用户有两个角色,买家和卖家。您需要小心使用您的关联名称,
@user.offers
是否返回用户提供的优惠,或用户收到的优惠?您可能希望能够在用户的配置文件中列出这两项内容

您描述的基本关系相当简单:

  • 一个用户可以销售很多产品,所以
    用户有很多:产品
    产品属于:用户

  • 一个用户可以提供很多优惠,因此
    用户有很多:优惠
    并且
    优惠属于:用户

  • 一个产品可能会收到许多优惠,因此
    产品有许多:优惠
    优惠属于:产品

这一切都很好,你当然可以这样做——在这种情况下,你可以跳到第2部分:)

然而,一旦你开始尝试通过
关系添加
,水就会变得浑浊。毕竟,

  • 报价属于用户(买方),但也有一个用户通过产品(卖方)

  • 用户有很多:产品(他们正在销售),但他们也有很多通过优惠购买的产品(他们正在购买-嗯,尝试购买)

啊,搞糊涂了

这就是您需要
: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
虽然如果将
产品
表中的
用户id
列重命名为
卖方id
,以及
优惠
表中的
买方id
,您将不需要这些
:外键
选项

第2部分:接受/拒绝报价

class User < ActiveRecord::Base
  attr_accessible :name, :email, :password, :password_confirmation, :remember_me, :avatar, :screen_name
  has_many :owned_products, :class_name => "Product"
  has_many :offers 
  has_many :interested_products, :through => :offers
end

class Offer < ActiveRecord::Base
  attr_accessible :offer_price, :status, :user_id, :product_id
  belongs_to :interested_user, :class_name => "User", :foreign_key => :user_id
  belongs_to :interested_product, :class_name => "Product", :foreign_key => :product_id
end

class Product < ActiveRecord::Base
  attr_accessible :content, :price, :title, :tag_list, :productimage, :user_id
  belongs_to :owner, :foreign_key => :user_id, :class_name => "User"
  has_many :offers 
  has_many :interested_users, :through => :offers
end
有很多方法可以解决这个问题。我会将一个布尔字段
accepted
放在
Offer
上,然后您可以得到如下内容

# Offer
def accept
  self.accepted = true
  save
end

def reject
  self.accepted = false
  save
end
您可以找到未完成的报价(其中,
已接受
为空)

为了获得控制器中的接受/拒绝逻辑,您可以考虑(链接指南是另一个值得深入阅读的)。你应该找一条像这样的线

resources :offers
在config/routes.rb中,它提供标准操作
索引
显示
编辑
,等等。您可以将其更改为

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
然后您可以向
offers/3/accept
发出POST请求,这将导致id为3的报价被接受。像这样的
def accept
  offer = current_user.offers_received.find(params[:id])
  offer.accept
end

# similarly for reject
link_to "Accept this offer", accept_offer_path(@offer), method: :post