【问题标题】:ActiveRecord Join table for legacy Database旧数据库的 ActiveRecord 连接表
【发布时间】:2009-07-24 20:13:08
【问题描述】:

我有一个旧数据库,我正在努力让 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。我怎么去那里?

【问题讨论】:

    标签: ruby-on-rails ruby database activerecord legacy


    【解决方案1】:

    我相信,使用 has_and_belongs_to_many 的选项,您可以比 Alvaro 的回答稍微优雅一些​​,尽管他的回答非常好,并且将为您班级的任何客户带来完全相同的功能。

    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,但我想这个例子是,如果一个节目有一个衍生系列,在他们各自的系列中的某个时候,他们可能会有一个情节,其中两个一起来。无论如何,通过 activerecord 让别人的数据库具有逻辑意义是很有趣的。
    【解决方案2】:

    这项工作适合你...

    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
    

    【讨论】:

      【解决方案3】:

      关系是一对多的,所以你需要在表中使用belongs_to/has__many 关系。如果您的数据库有视图,您可以通过表的视图来屏蔽非标准外键。

      不确定这是否能 100% 满足您的需求,但我希望它至少能给您一个想法。

      【讨论】:

      • 有趣的想法。我以前没有使用过数据库视图。我没有能力更改数据库的任何内容,所以我不确定数据库视图是否可以在这里工作。关于 has_and_belongs_to_many 关系的主题,如果我有非标准的主键,那不会分崩离析吗?我认为通过使用第三种模型,我可以建立 has_and_belongs_to_many_through 关系。
      • 呃在上面的回复中使用非标准的外来键:关于 has_and_belongs_to_many 关系的主题,如果我有非标准的 foreign钥匙?
      • 嗯,想法是您使用标准外键,视图基本上将您的标准外键转换为表中的非标准外键。视图可以像重命名字段一样简单(即 CREATE VIEW TvShowView AS SELECT tvshow,idShow AS Show_id FROM TvShow)。只要视图与表具有一对一的关系,您也可以将其用于插入和更新。
      【解决方案4】:

      有了这个,你不需要设置表格视图,实际上,表格视图不是“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
      

      【讨论】:

        猜你喜欢
        • 2014-02-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-12-15
        • 2014-07-10
        • 2014-07-04
        • 1970-01-01
        • 2012-04-28
        相关资源
        最近更新 更多