活动记录(ActiveRecord)连接遗留数据库的表格

5

我正在处理一个遗留数据库,需要让ActiveRecord与其配合使用。但是在联接表方面遇到了问题。具体来说,我的情况如下:

class TvShow < ActiveRecord::Base

  set_table_name "tvshow"
  set_primary_key "idShow"

end

class Episode < ActiveRecord::Base
  set_table_name "episode"
  set_primary_key "idEpisode"
end

然后我有一个名为tvshowlinkepisode的表,其中有2个字段:idShow,idEpisode。因此,我有2个表和它们之间的连接(因此是多对多关系),但连接使用非标准外键。我的第一个想法是创建一个名为TvShowEpisodeLink的模型,但没有主键。我的想法是,由于外键是非标准的,我可以使用set_foreign_key并进行一些控制。最终,我想说类似于TvShow.find(:last).episodes或Episode.find(:last).tv_show这样的话。如何实现这一点?

4个回答

8

我相信你可以比Alvaro的答案更加优雅地使用has_and_belongs_to_many的选项,尽管他的答案完全没问题,并且对于任何客户端的类都会产生几乎相同的功能。

class TvShow < ActiveRecord::Base

  set_table_name "tvshow"
  set_primary_key "idShow"
  has_and_belong_to_many :episodes, 
                         :join_table => "tvshowlinkepisode", 
                         :foreign_key => "idShow",
                         :association_foreign_key => "idEpisode"

end

class Episode < ActiveRecord::Base
  set_table_name "episode"
  set_primary_key "idEpisode"
  has_and_belongs_to_many :tv_shows,
                          :join_table => "tvshowlinkepisode",
                          :foreign_key => "idEpisode",
                          :association_foreign_key => "idShow"
end

请注意,:foreign_key选项指定了“此侧”链接类的id是哪一列,而:association_foreign_key指定了“另一侧”链接类的id是哪一列。与Alvaro的答案相比,这种模式应该避免实例化任何不必要的对象来表示链接。

我认为一集节目只能属于一个特定的电视节目,而不是多个。 - txwikinger
我也这么认为,@txwikinger,但我猜这个例子是,如果一个节目有一个衍生系列,在它们各自的系列中可能会有一集两者相遇。无论如何,通过activerecord让别人的数据库变得有逻辑意义是很有趣的。 - user137848

5

这项工作适合你...

class TvShow < ActiveRecord::Base
  set_table_name "tvshow"
  set_primary_key "idShow"

  has_many :tv_show_link_episode, :foreign_key => 'idShow'
  has_many :episodes, :through => :tv_show_link_episode
end


class Episode < ActiveRecord::Base
  set_table_name "episode"
  set_primary_key "idEpisode"

  has_many :tv_show_link_episode, :foreign_key => 'idEpisode'
  has_many :tv_shows, :through => :tv_show_link_episode

end

class TvShowLinkEpisode  < ActiveRecord::Base
  set_table_name "tvshowlinkepisode"

    # the foreign key is named by the TvShowLinkEpisode field, 
    # the primary key name is for the primary key of the associated class
    belongs_to :tv_show, :foreign_key => 'idShow'
    belongs_to :episode, :foreign_key => 'idEpisode'
end

0

有了这个,你就不需要设置表视图,实际上,表视图并不是“Rails Way”。

试试这个:

>> TvShow.find(1).episodes 
#=> returns an array with [#<Episode idEpisode: 1, test: "Episode 1">]

>> Episode.find(1). tv_shows 
#=> returns an array with [#<TvShow idShow: 1, test: "tvshow 1">]

然后你可以做一些操作,比如:

e = Episode.find(1)
TvShow.find(1). episodes << e
#=> this make the proper association

0

关系是一对多的,因此您需要在表中使用belongs_to/has_many关系。如果您的数据库有视图,您可以通过为表创建视图来掩盖非标准外键。

不确定是否完全符合您的需求,但我希望至少能给您一个想法。


有趣的想法。我以前没有使用过数据库视图。我无法更改数据库中的任何内容,因此我不确定数据库视图是否适用于此处。关于has_and_belongs_to_many关系,如果我有非标准主键,那么这个关系会崩溃吗?我认为通过使用第三个模型,我可以进行has_and_belongs_to_many_through关系。 - user137848
请将上面的响应中的“Er make that non-standard foreign in key”翻译为非标准外键:关于has_and_belongs_to_many关系,如果我有非标准的外键,这个关系不会崩溃吗? - user137848
好的,这个想法是使用标准外键,视图基本上将您的标准外键转换为表中的非标准外键。 视图可以简单地重命名字段(即CREATE VIEW TvShowView AS SELECT tvshow,idShow AS Show_id FROM TvShow)。 只要视图与表具有一对一的关系,您也可以将其用于插入和更新。 - txwikinger

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接