Rails 3.1具有复合主键的嵌套资源(id + parent_id)

时间:2011-12-11 12:20:14

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

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

resources :post do
  resources :comment
end

按照惯例 comments.id 将是评论主键 comments.post_id 将是外键

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

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

当然,我还需要禁用每个引用注释的路由(子资源),而不需要引用它的帖子(父资源)。

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

谢谢。

3 个答案:

答案 0 :(得分:3)

执行此操作的一种方法是创建另一列(保留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)

请注意,此处的实际逻辑应调整以满足您的要求。例如,如果可以删除注释,那么在post上保留一个用于确定下一个sub_id(或写一个sub id生成器类)的计数器可能是一个好主意。

答案 1 :(得分:1)

实际上我不太确定你想要完成什么以及为什么?也许你冷得让它更清晰一些。无论如何两个链接可能会有所帮助:

Composite Primary Keys in Rails

Rails Associations

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

答案 2 :(得分:0)

只是旁注:可能是逻辑上的

before_create do     this.sub_id = post.comments.size + 1 端

应该通过适当处理删除评论来备份

。否则我们很快会遇到重复的sub_ids。