列trades.item_id为什么不存在?
我有一个关系模型,其中两个用户可以进入交易两个项目交换。列trades.item_id为什么不存在?
class User < ActiveRecord::Base
has_many :owned_items, class_name: "Item"
has_many :trades_received, class_name: "Trade", through: :owned_items, source: :trades
has_many :trades
has_many :wanted_items, class_name: "Item", through: :trades, source: :item
end
class Item < ActiveRecord::Base
belongs_to :owner, class_name: "User", foreign_key: :user_id
has_many :trades, dependent: :destroy
has_many :trade_requesters, through: :trades
has_many :trade_recipients, through: :trades
end
class Trade < ActiveRecord::Base
belongs_to :trade_requester, class_name: "User"
belongs_to :trade_recipient, class_name: "User"
belongs_to :wanted_item, class_name: "Item", foreign_key: :wanted_item_id
belongs_to :collateral_item, class_name: "Item", foreign_key: :collateral_item_id
end
迁移我的交易表看起来像这样:
create_table :trades do |t|
t.belongs_to :trade_requester
t.belongs_to :trade_recipient
t.belongs_to :wanted_item
t.belongs_to :collateral_item
end
堆栈跟踪导致我使用列出所有交易请求一个辅助方法。该行表示@trades = current_user.trades_received.requested.count
,然后放到模型关联的User上,其中has_many :owned_items, class_name: "Item"
。根据我的理解,它看起来像trades_received
方法,它被称为through: :owned_items
和source: :trades
应该引用:wanted_item_id
外键进行迁移。但事实并非如此。如果我创建一个迁移来添加item_id
,但它有效,但贸易需要两个项目,所以我已将它分成两个wanted_item
和collateral_item
关联。如何设置该用户关联以便引用其他用户请求的项目?应该项目has_many :trades
,我的方式,或者应该项目belongs_to :trades
?
完整的错误:
PG::UndefinedColumn: ERROR: column trades.item_id does not exist
LINE 1: ...LECT COUNT(*) FROM "trades" INNER JOIN "items" ON "trades"."...
^
: SELECT COUNT(*) FROM "trades" INNER JOIN "items" ON "trades"."item_id" = "items"."id" WHERE "items"."user_id" = $1 AND "trades"."approved" IS NULL
tldr:我需要跟踪一堆复杂的has_many :through
协会,我不认为我的数据模型是正确的,需要帮助理解为什么。谢谢。
您正在设置User
和Item
之间的两个has_many :through
关系,并将Trade
作为两者的连接表。你有一些关系困惑。这是根据您的迁移设置:
class User < ActiveRecord::Base
has_many :received_trades, class_name: "Trade", foreign_key: "trade_recipient"
has_many :requested_trades, class_name: "Trade", foreign_key: "trade_requester"
has_many :collateral_items, through: :received_trades
has_many :wanted_items, through: :requested_trades
end
class Item < ActiveRecord::Base
has_many :collateral_items, class_name: "Trade", foreign_key: "collateral_item"
has_many :wanted_items, class_name: "Trade", foreign_key: "wanted_item"
has_many :trade_requesters, through: :wanted_items
has_many :trade_recipients, through: :collateral_items
end
class Trade < ActiveRecord::Base
belongs_to :trade_requester, class_name: "User"
belongs_to :trade_recipient, class_name: "User"
belongs_to :wanted_item, class_name: "Item"
belongs_to :collateral_item, class_name: "Item"
end
##migration
create_table :trades do |t|
t.belongs_to :trade_requester
t.belongs_to :trade_recipient
t.belongs_to :wanted_item
t.belongs_to :collateral_item
end
一些解释:
Item has_many :collateral_item ## item_id in table collateral_items
Item has_many :collateral_item, class_name: "Trade", foreign_key: "collateral_item"
##collateral_item_id in trades table.
好吧,好吧。问题就在这里:
has_many :trades, dependent: :destroy
而在你Trade
型号:
belongs_to :wanted_item, ...
belongs_to :collateral_item, ..
的Rails不能自动处理这个问题。
你需要做的这个步骤之一(具体取决于您在您的应用程序的需要):
如果需要单独的关联:
class User < ActiveRecord::Base
has_many :trades_received, class_name: "Trade", through: :owned_items, source: :wantable_trades
end
class Item < ActiveRecord::Base
has_many :wanted_trades, class_name: 'Trade', inverse_of: :wanted_item, dependent: :destroy
has_many :collateral_trades, class_name: 'Trade', inverse_of: :collateral_item, dependent: :destroy
end
如果你需要的所有交易单的关联:
那么,你会有一个痛苦的屁股:)在这种情况下,你应该手动选择关联,或重新考虑你的数据模型。
你是指“手动选择关联还是重新考虑数据模型?” ':wanted_trades'和':trades_received'不是单独的关联吗?另外,为什么在Item模型中有两次':wanted_trades'?那不就是两次引用同一个项目吗? – sabaeus
@sabaeus对不起,我不小心丢弃了编辑。更新了我的答案。 物品不能只是“有很多交易”,因为从贸易到物品('item_id'或其他)没有直接的联系。所以你必须分开关联。如果要选择,你必须手动SELCT他们项目的所有行业('Trade.where(“wanted_item_id =?或collateral_item_id =?”,self.id')或改变你的数据库架构。 – unkmas
天上,等等'inverse_of '创建链接?哇,终于是有道理的。谢谢!我很困惑的另一问题,虽然。你是说手动选择是不妥当的,或可能是一个痛苦?我只问,因为我最初的职位有多个关联贸易,但你的回答说:“如果你需要的所有交易作为一个单一的协会” – sabaeus
'用户的has_many:trades_received'。所以它应该是'current_user.trades_receiveds'。可能更好地将其更改为'received_trades'。你的'#requested'方法是什么?哪条确切的线给你的错误? – EJ2015
'requested'是一个范围,它只是'scope:requested, - > {where(approved:nil)}'。我的错误来自于我在头文件中使用的帮助器,并且涉及用户模型的':trades_received'关联。@unkmas认为这是由于我的设置在Trade和Item之间没有直接联系。 – sabaeus
@sabaeus可以粘贴数据库schema文件 – krishnar