web-dev-qa-db-ja.com

Railsおよび共有システムを実装するMongoidの最良の方法

私はモデル化する必要がありますユーザーボード Rails in mongoid as ODM。

各ボードは、外部キーser_idを介してユーザーに参照されます。次に、ボードを他のユーザーと共有する機能を追加します。

CRUDに続いて、Shareのような新しいモデルを作成します。これは、共有を作成/編集/削除する機能を持つ関連コントローラーですが、いくつかの疑問があります。

  1. 最初に、Sharesに関する情報をどこに保存しますか?ユーザーIDの配列を含むshared_withと呼ばれるボードのコレクションにフィールドを作成できると思います。 MySQLで、whoの共有ID、共有されるリソース、リソースが共有されるユーザーのIDを使用して新しいテーブルを作成しましたが、MongoDBを使用する必要はないと思います。
  2. ボードを共有しているすべてのユーザーは、ボードを編集できる(ただしボードを削除できない)必要があるため、ボードには所有者との関係と、ボードを共有しているユーザーとの関係の2つが必要です。
  3. 許可のために(所有者はボードを削除できるはずですが、ボードを共有しているユーザーはできません)何を使用しますか?私は認証にDeviseを使用していますが、CanCanのようなものがより適していると思います。しかし、それを実装する方法は?

この方法についてどう思いますか?問題を見つけたり、より良い解決策がありますか?

4

RDBMSのようなソリューションのように見えますが、私は一般的にあなたのソリューションに同意し、私は同じことをします。つまり、Shareという別のモデルを作成します。

しかし、一歩下がって、利用可能なオプションを確認しましょう。

まず、モデルの関係を検討します。一枚の紙にそれらを描き、関係のタイプとそれらの関連に注意してください(所属する、1つある、ある、多くある、たくさんある、またはhas_and_belongs_to_many)。 Rails is http://guides.rubyonrails.org/association_basics.html の関連付けの完全な参照。Mongoidはembedded_in/embeds_manyタイプも提供していることを考慮してください関係。

あなたの場合、関係は次のようになります:所有するためのユーザー(1..N)ボード、共有するためのユーザー(N..N)ボード。

Has_many、has_and_belongs_to_many、またはembeds_manyを使用するかどうかを決定するヒントは、従属モデルが意味的に埋め込まれたタイプの関係を表し、親以外の他のモデルと接続されていないかどうかです。それはそうです、embeds_manyを使用してください、そうでなければhas_manyまたはhas_and_belongs_to_manyを使用してください。

Has_many:throughまたはhas_and_belongs_to_manyのどちらを使用するかを決定するヒントは、リンクモデルにデータを追加するかどうかです(この場合は共有)。

mongoidのhas_and_belongs_to_manyは、リンクモデルを作成せずに実行しています。つまり、board_idsはUserモデルの配列として保持され、user_idsはBoardモデルの配列として保持されます。

あなたのケースでHABTMを使用しない理由は簡単です。ユーザーモデルとボードモデルの間に2つの関係(共有と所有)があり、user.boardsのような式(共有ボードまたは所有ボード)の意味を理解するのが難しい場合があります。コメントで提案したように(:asなどを使用して)、3番目のモデル(共有)を使用せずにこれらの2種類の関係を簡単に分離する方法はわかりません

次のように、ユーザーモデルにボードのIDを手動で保持することもできます。

class User
  include Mongoid::Document
  field :name
  key :shared_board_ids, Array, :index => true
  key :owned_board_ids, Array, :index => true

  def shared_boards
    Board.find shared_board_ids
  end
  # ...

end

ただし、この場合の問題はかなり早く発生します。ボードを破棄するときは、ユーザーモデルからすべてのボード参照を手動で破棄する必要があります。ボードモデルでsharing_user_idsを維持すると、冗長性が生じ、別の問題が発生します。

ですから、以下に示すように、別の共有モデルを作成することをお勧めします。

class User
  include Mongoid::Document
  field :name
  has_many :shares
  has_many :boards
end

class Board
  include Mongoid::Document  
  field :title
  has_many :shares
  belongs_to :user
end

class Share
  include Mongoid::Document  
  belongs_to :user
  belongs_to :board
end

権限に関しては、CanCanは単純ですが、問題なく動作しています。認証(ユーザーの信憑性をチェックします。つまり、ユーザーが本人であると主張していることを確認します-通常はパスワードを使用します)と承認(ユーザーの権限をチェックします)の違いに注意してください。認証は、Authlogic、Warden(およびWardenに基づくDevise)、Sorceryなどのgemによって処理されます。承認はDeclarative_authorizationまたはCanCanによって処理されます。

4

私はあなたがスタックオーバーフローでより良い答えを見つけるかもしれないと思います。私はRailsまたはmongodbの専門家ではありませんが、やってみます。

  1. 理事会のコレクションにフィールドを作成しても、おそらく問題はありません。

  2. 単一のリレーションコレクションを作成し、リレーションにタイプを追加することができます。そうすることで、必要に応じて複数の所有者を作成し、後で「読み取り専用」やブロックなどのタイプを追加できます。

  3. 共有されているかどうか、および所有者であるかどうかに基づいて、タイプとレンダリングビューを確認します。このためのアクセス許可フレームワークは必要ないと思いますが、それを許可するのが悪い考えではありません。

お役に立てば幸いです。

0
Owen Johnson