【问题标题】:Rails 3.1 nested resource with composite primary key (id + parent_id)具有复合主键(id + parent_id)的 Rails 3.1 嵌套资源
【发布时间】:2011-12-11 12:20:14
【问题描述】:

假设我需要嵌套在 routes.rb 中的两个资源,如下所示:

resources :post do
  resources :comment
end

按照惯例 cmets.id 将是 cmets 主键cmets.post_id 将是 外键.

我需要 主键 作为 复合键 [cmets.post_id, cmets.id]

这样我就可以获得每个 id == 1 的不同帖子的每条第一条评论,每个 id == 2 的不同帖子的每条第二条评论等等......

当然,我还需要禁用所有引用评论(子资源)而不引用其帖子(父资源)的路由。

这只是一个示例,我的实际项目与博客无关(我对这个问题的处理方式不同),我想知道是否有办法按顺序为嵌套资源实现这种行为以实现与旧数据库的兼容性。

谢谢。

【问题讨论】:

    标签: ruby-on-rails ruby-on-rails-3.1 composite-primary-key nested-resources


    【解决方案1】:

    一种方法是创建另一列(将 posts.id 保留为主键),在该列上添加唯一性验证,范围为 post id,然后在 _create hood 之前或之后编写一些以生成该列值。

    一个例子(不是真实的代码)

    class Comment < ActiveRecord::Base
      ...
      validates_uniqueness_of :sub_id, :scope => :post_id
    
      before_create do
        this.sub_id = post.comments.size + 1
      end
    end
    

    因此 sub_id 列充当主键。当您查询某个帖子的评论时,您可以这样做:

    post.comments.where(:sub_id => val).first
    

    post.comments.find_by_sub_id(val)
    

    请注意这里的真实逻辑应该调整以满足您的要求。例如,如果可以删除 cmets,最好在 post 上保留一个计数器,用于确定下一个 sub_id(或编写一个子 id 生成器类)。

    【讨论】:

      【解决方案2】:

      实际上,我不太确定您要完成什么,为什么?也许你冷得更清楚一点。无论如何,两个链接可能会有所帮助:

      Composite Primary Keys in Rails,

      Rails Associations

      所以,如果可以的话,我会使用上面第二个链接中解释的第三个模型来实现它。如果那是不可能的,您可能想尝试第一个链接中提到的 gem。

      【讨论】:

      • 我正在尝试完成一个嵌套(子)资源,使其所属的每个父资源都有一个从 1 开始的 id 编号。为什么?因为我需要遵守一些遗留要求...我根据您的建议编辑了问题,试图更清楚。
      【解决方案3】:

      只是一个旁注:可能是合乎逻辑的

      before_create 做 this.sub_id = post.cmets.size + 1 结束

      应通过适当处理删除 cmets 来备份。否则我们很快就会遇到重复的 sub_ids。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-08-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-01-10
        相关资源
        最近更新 更多