2012-09-26 61 views
0

我已經設置了這樣的事情我的一個項目的模型(用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合作。我想用indexshow方法,只允許進入學校的家長在孩子一SchoolController要做到這一點,最好的辦法,根據該網站: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不是可以使用的方法。有沒有辦法從一組文檔創建關聯代理?還是有更聰明的方法來處理這個簡單的訪問控制問題?

回答

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 

不知道有沒有更好的方法,在這一點上。