假设我需要在路由中嵌套两个资源。
resources :post do
resources :comment
end
按照约定注释。id将是注释主键和注释。post_id将是外键。
我需要主键是复合键[comments]。post_id comments.id] .
这样我就可以得到id == 1的每个不同帖子的第一条评论,id == 2的每个不同帖子的第二条评论,以此类推…
当然,我还需要禁用所有引用评论(子资源)而不引用其帖子(父资源)的路由。
这只是一个例子,我的实际项目不是关于博客(我处理这个问题不同),我想知道是否有一种方法来实现嵌套资源的这种行为,以实现与遗留数据库的兼容性。
谢谢。
实现此目的的一种方法是创建另一个列(离开帖子)。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(或编写一个subid生成器类)。
实际上我不太确定你想要完成什么,为什么?也许你能说得更清楚一点。无论如何,两个链接可能会有所帮助:
Rails中的复合主键,
Rails协会所以,如果可以的话,我会使用上面第二个链接中解释的第三个模型来实现它。如果这是不可能的,你可能想尝试他们在第一个链接中提到的。
旁注:可能是逻辑上的错误
before_create做这一点。Sub_id = post.comments.size + 1
结束应该通过适当的删除注释处理来备份。否则,我们很快就会遇到重复的sub_id。