2012-09-26 62 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 

不知道有没有更好的方法,在这一点上。