我有一个我的项目模型设置为这样的东西(使用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
My Parent模型充当我使用Devise设置的标准用户模型。我希望SchoolController
使用index
和show
方法,只允许访问父母有孩子的学校。根据此网站,最好的方法是执行此操作:{{ 3}},就是这样做:
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 :(得分: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
这样我可以保持我的Controller逻辑简单和一致:
class ParentsController < ApplicationController
def show
@school = current_user.schools.find(params[:id])
end
end
目前还不确定是否有更好的方法。