第一件事
使用:
我在现有数据库上映射了许多到多个关系。我的模特看起来是这样的:
class EventMap < ActiveRecord::Base
self.table_name="TAKE_PART"
self.primary_key="id"
belongs_to :event, foreign_key: "lottery_event_id"
belongs_to :entrant, foreign_key: "address_id"
end
class Event < ActiveRecord::Base
self.table_name="THE_EVENT"
self.primary_key="id"
has_many :event_maps
has_many :entrants, :through => :event_maps
end
class Entrant < ActiveRecord::Base
self.table_name="ADDRESSES"
self.primary_key="id"
self.set_date_columns :date_of_birth
has_many :event_maps
has_many :events, :through => :event_maps
end当我试图获取事件的所有地址时:
def show
@entrants = Event.find(params[:id]).entrants
end我得到了这样一个Oracle错误:
OCIError: ORA-00904: "TAKE_PART"."ENTRANT_ID": SELECT "THE_EVENT".* FROM "THE_EVENT" INNER JOIN "TAKE_PART" ON "THE_EVENT"."ID" = "TAKE_PART"."LOTTERY_EVENT_ID" WHERE "TAKE_PART"."ENTRANT_ID" = :a1这里的问题似乎是TAKE_PART的外键使用不当,应该是address_id,而是使用模型名entrant_id。
这是oracle中的一个bug增强了,还是我在表的匹配上做错了什么?
发布于 2013-10-24 13:28:50
类的关联还没有完全定义,bc Event和Entrant都不知道正确的ids,它们应该传递给EventMap。适当的办法如下:
class EventMap < ActiveRecord::Base
...
belongs_to :event, :foreign_key => "lottery_event_id"
belongs_to :entrant, :foreign_key => "address_id"
end
class Event < ActiveRecord::Base
...
has_many :event_maps, :foreign_key => "lottery_event_id"
has_many :entrants, :through => :event_maps
end
class Entrant < ActiveRecord::Base
...
has_many :event_maps, :foreign_key => "address_id"
has_many :events, :through => :event_maps
end它之所以有效,是因为event.entrants意味着对数据库(简化)执行以下操作:
连接两个表
EventMap和Entrant,以便address_id <=> entrant.id (映射1) 在联接表中查找所有具有lottery_event_id = event.id (映射2)的字符串
映射1
has_many :entrants, :through => :event_maps #Join two tables
belongs_to :entrant, :foreign_key => "address_id" #matching address_id with entrants.id
#belongs_to+foreign_key tells to EventMap which key to use for referring to Event object映射2
has_many :event_maps, :foreign_key => "lottery_event_id" #associate event.id with lottery_event_id
#has_many+foreign_key tells to Event which key EventMap uses for referring to Event object或以更正式的方式:
SELECT "entrants".* FROM "entrants" INNER JOIN "event_maps" ON "entrants"."id" =
"event_maps"."address_id" WHERE "event_maps"."lottery_event_id" = ? [["lottery_event_id", 1]]https://stackoverflow.com/questions/19559826
复制相似问题