1

Let's assume I need two resources nested in the routes.rb as follows:

resources :post do
  resources :comment
end

By convention comments.id will be the comments primary key and comments.post_id will be a foreign key.

I need the primary key to be the composite key [comments.post_id, comments.id].

So that I could have every first comment of each distinct post with id == 1, every second comment of each distinct post with id == 2 and so on...

Of course I also need to disable every route that refers to a comment (the child resource) without referring also to its post (the parent resource).

This is just an example, my actual project isn't about a blog (I'd handled this problem differently), I'd like to know if there is a way to achieve such a behavior for a nested resource in order to achieve compatibility with a legacy database.

Thank you.

Darme
  • 6,984
  • 5
  • 37
  • 52

3 Answers3

3

One way to do this is by creating another column (leave the posts.id as it was primary key), add an uniqueness validation on that column with scope to the post id, then write some before or after _create hood to generate that column value.

An example (not real code)

class Comment < ActiveRecord::Base
  ...
  validates_uniqueness_of :sub_id, :scope => :post_id

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

So the sub_id column acts as a primary key. When you query a comment for a certain post, you do this:

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

or

post.comments.find_by_sub_id(val)

Please be noted the real logic here should be adjusted to satisfy your requirement. For instance, if comments can be deleted, it might be a good idea to keep an counter on post which will used to determine the next sub_id (or write a sub id generator class).

James Chen
  • 10,794
  • 1
  • 41
  • 38
1

Actually I am not quite sure what you are trying to accomplish and why? Maybe you cold make that a bit clearer. Anyway two links which might help:

Composite Primary Keys in Rails,

Rails Associations

So, if you can I would implement that using a third model as explained in the second link above. If thats is not possible, you might want to try them gem mentioned in the first link.

Community
  • 1
  • 1
jagse
  • 333
  • 4
  • 18
  • I'm trying to accomplish a nested (child) resource to have an id numeration starting from 1 for every parent resource it belongs_to. Why? Because I need to comply with some legacy requirements... I edited the question on your suggestion trying to be clearer. – Darme Dec 11 '11 at 14:22
0

Just a side note: Probably logic a la

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

should be backed up by suitable handling of deleting comments. Otherwise we would soon run into duplicate sub_ids.