質問

オブジェクトが別のクラスの正確に n 個のオブジェクトに関連付けられている関係をモデル化する最良の方法は何だろうと考えていました。has_one 関係を特定の値 n まで拡張したいと考えています。

たとえば、TopFiveMoviesList はユーザーに属し、ちょうど 5 つの映画が含まれます。基礎となるSQLテーブルにはmovie_id_1、movie_id_2などのフィールドがあると想像します。movie_id_5。

has_many リレーションシップを使用してモデル レベルで子の数を制限できることはわかっていますが、中間テーブルは使用したくありません。

役に立ちましたか?

解決

私の最初の直感は結合テーブルを使用することですが、それが望ましくない場合は User.movie[1-5]_id 列は法案に適合するでしょう。(私は思う movie1_id よりも Rails の規約によく適合します movie_id_1.)

この Rails と ActiveRecord にタグを付けたので、完全にテストされておらず、おそらく多少間違っているモデル コードを回答に追加します。:)

class User < ActiveRecord::Base
  TOP_N_MOVIES = 5
  (1..TOP_N_MOVIES).each { |n|  belongs_to "movie#{n}".to_sym, :class_name => Movie }
end

その行をマクロ スタイルのメソッドで囲むこともできますが、それがアプリケーションの一般的なパターンでない限り、コードを読みにくくするだけで、DRY の利点はほとんどありません。

ユーザーのリストに重複した映画がないことを確認するための検証を追加することもできます。

ムービー クラスをユーザーに再度関連付けることも同様です。

class Movie < ActiveRecord::Base

  (1..User::TOP_N_MOVIES).each do |n| 
    has_many "users_list_as_top_#{n}".to_sym, :class_name => User, :foreign_key => "movie#{n}_id"
  end

  def users_list_as_top_anything
    ary = []
    (1..User::TOP_N_MOVIES).each {|n| ary += self.send("users_list_as_top_#{n}") }
    return ary
  end

end

(もちろんそれは users_list_as_top_anything おそらく明示的な SQL として記述したほうがよいでしょう。今日は怠け者です。)

他のヒント

ここでは、結合モデルを通じてこのモデルを実装するのが最善の策であると思います。それは、 List リストロジックと Movie ムービーロジックが気になるモデル。作成できます Nomination (名前は最高ではありませんが、私が言いたいことはわかるでしょう)映画とリストの関係を処理するためのモデルで、5 つの制限がある場合は、撤回するノミネートの数を制限するだけで済みます。

このアプローチがより良いと考える理由はいくつかあります。

まず、関係を双方向で横断できるようにしたいと仮定します (movie.lists そして list.movies)、5 列のアプローチはさらに複雑になります。

ActiveRecord がサポートするほうがはるかに良いですが、 has n 人間関係に関してはそうではないので、その枠組みと戦うことになるでしょう。また、 has n この状況では、関係が少し不安定に思えます。私は ActiveRecord でそのような実装が成功したのを見たことがありませんが、それが実現するのを見ることに非常に興味があります。:)

「実装」を意味すると思います; 「モデル」ではなく? 5つのMovieエンティティで構成されるPersonエンティティがある場合、UMLではモデリングは非常に簡単です。

しかし、has_oneと言ってhas_5に行くと困難が生じます。単純なスカラー値の場合、has_oneはおそらく親エンティティのプロパティです。 Has_5は、おそらく「から構成される」を通じて互いに関連する2つのエンティティです。 UMLの関係。

答える主な質問は、おそらく「常にトップ5」になることを保証できますか?」はいの場合、前述のように列でモデル化します。いいえの場合、別のエンティティでモデル化します。

もう1つの質問は、「リファクタリングはどれくらい簡単ですか?」です。単純な場合は、5列から始めて、リファクタリングしてエンティティを変更します。

いつものように、「最高」ビジネスおよび技術環境に依存しています。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top