0

プロジェクトの 1 つのモデルを次のように設定しています (Rails 3.2 と Mongoid 3.0 を使用):

class Parent
  include Mongoid::Document

  has_many :kids

  def schools
    return kids.map { |kid| kid.school }
  end
end

class School
  include Mongoid::Document

  has_many :kids
end

class Kid
  include Mongoid::Document

  belongs_to :parent
  belongs_to :school
end

親モデルは、Devise でセットアップした標準のユーザー モデルとして機能します。SchoolController親が子供がいる学校へのアクセスのみを許可するindexandメソッドが必要showです。このサイトによると、これを行う最良の方法: http://www.therailsway.com/2007/3/26/association -proxies-are-your-friend/は、次のようなことを行います:

def index
  @schools = current_user.schools
end

def show
  @school = current_user.schools.find(params[:id])
end

ただし、Mongoid はhas_many :throughリレーションを許可しないためParent#schools、連想プロキシではなく配列を返すカスタム メソッドであるため、#find使用できるメソッドではありません。ドキュメントの配列から関連付けプロキシを作成する方法はありますか? または、この単純なアクセス制御の問題を処理するよりスマートな方法はありますか?

4

1 に答える 1

0

これまで私がこれを解決できた最も洗練された方法は、によって返される配列にカスタムメソッドをアタッチすることParents#schoolsです。

返された配列に#findメソッドを与えます:

class Parent
  include Mongoid::Document

  has_many :kids

  def schools
    schools = self.kids.map { |kid| kid.school }

    # Returns a school with the given id. If the school is not found, 
    # raises Mongoid::Errors::DocumentNotFound which mimics Criteria#find.
    def schools.find(id)
      self.each do |school|
        return school if school.id.to_s == id.to_s
      end
      raise Mongoid::Errors::DocumentNotFound.new(School, {:_id => id})
    end

    return schools
  end
end

そうすれば、コントローラーロジックをシンプルで一貫性のあるものに保つことができます。

class ParentsController < ApplicationController

  def show
   @school = current_user.schools.find(params[:id])
  end

end

この時点でもっと良い方法があるかどうかはわかりません。

于 2012-09-26T19:40:27.957 に答える