1878


例えば以下のようなルーティングで実現するようなネストしたリソースにおいて

[code]

    resources :parents do
      resources :children
    end
    
[/code]

それぞれのparentの子リソースであるchildrenに1から始まる番号を付けたい時(/parents/1/children/1/と/parents/2/children/1/は違うリソースを指すようにしたいが、ID自体は1からauto
incrementさせたい)はどのような方法が一番良いですか。


CC BY-SA 3.0
2014-12-16T10:33:58.127
1739
2014-12-17T06:25:38.550
2014-12-16T12:53:38.600
30
3069
question
ruby-on-rails
Ruby on RailsのネストしたリソースのIDを個別に1からauto incrementさせたい


まさに私が意図していた事と同じ質問が英語版のStack Overflowに存在しました
(<https://stackoverflow.com/questions/8463891/rails-3-1-nested-resource-with-
composite-primary-key-id-parent-id>)。

>
> 一つ考えられる方法は、別のカラムを作って(idはプライマリキーとしてそのまま残しておいて)、そのカラムに親リソースのIDをスコープとした一意性のバリデーションを追加して、そしてbefore_createかafter_createでそのカラムの値を生成することです。
>
> サンプル (実際のコードではない)
[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
>  
[/code]

>
> そうすれば、sub_idをプライマリキーのように使うことができます。例えば特定のpostのcommentを一つ取得したい時は
[code]

>     post.comments.where(:sub_id => val).first
>  
[/code]

>
> とか
[code]

>     post.comments.find_by_sub_id(val)
>  
[/code]

>
>
> とかすればいい訳です。注意すべき点は、このコードを実際に使う時はその時々の要件に合わせて変更を加えるべきだという事です。例えば、commentが削除できるのならば、次のsub_idの値を決めるために使うカウンタをpostに保存しておいたほうが良いのかもしれません。

まだ試していないのでまだ分かりませんが、"Composite Primary Keys for ActiveRecords"
([https://github.com/composite-primary-
keys/composite_primary_keys)というgemもこういう場合便利かもしれません](https://github.com/composite-
primary-
keys/composite_primary_keys\)%E3%81%A8%E3%81%84%E3%81%86gem%E3%82%82%E3%81%93%E3%81%86%E3%81%84%E3%81%86%E5%A0%B4%E5%90%88%E4%BE%BF%E5%88%A9%E3%81%8B%E3%82%82%E3%81%97%E3%82%8C%E3%81%BE%E3%81%9B%E3%82%93)。


CC BY-SA 3.0
2014-12-17T06:25:38.550
1878
2014-12-17T06:25:38.550
2017-05-23T12:38:56.083
-1
3069
1739
answer