我有以下型号:
class Post < ActiveRecord::Base
has_many :responses, as: :responseable, dependent: :destroy
end
class Call < ActiveRecord::Base
has_many :responses, as: :responseable, dependent: :destroy
end
class Meeting < ActiveRecord::Base
has_many :responses, as: :responseable, dependent: :destroy
end
class Response < ActiveRecord::Base
belongs_to :responseable, polymorphic: true # Tested
end
在CanCan中,我试图通过多态关联中的属性来定义特定自定义响应操作的功能。行动如下:
class ResponsesController < ApplicationController
before_filter :authenticate_user!
load_and_authorize_resource
respond_to :html, :xml, :js, :json, :pdf
# GET /responses/polling
# GET /responses/polling.json
def polling
responseable_type = params[:responseable_type]
klass = [Post, Call, Meeting].detect { |c| responseable_type}
@responseable = klass.find(params[:responseable_id])
@responses = @responseable.responses.where("created_at > ?", Time.at(params[:after]))
end
...
我的能力文件看起来像这样:
...
can :polling, Response, :responseable_type = "Post", :responseable => { :user_expert_private => false, :countries => { :id => user.country_ids} }
...
此操作通过javascript函数运行,该函数每5秒轮询一次新响应。但是,当运行时,我在日志中遇到以下错误:
A NameError occurred in responses#polling:
uninitialized constant Responseable
activesupport (3.2.8) lib/active_support/inflector/methods.rb:230:in `block in constantize'
有没有想过从多态关系中定义属性的正确方法?
基本上,我不希望用户能够查看/创建响应,除非他们can? show:
父对象。
答案 0 :(得分:1)
看看wiki article。有一个关于多态类型的部分。您需要使用嵌套授权。以下是相关部分:
假设任务可以分配给项目或事件 通过多态关联。一个数组可以传入 :通过选项,它将使用它找到的第一个。
load_resource :project
load_resource :event
load_and_authorize_resource :task, :through => [:project, :event]
这里它将检查@project和@event变量并获取 通过任何一个存在的任务。请注意,这只是加载 父模型,如果要授权您需要的父模型 通过before_filter来完成,因为涉及到特殊的逻辑。
before_filter :authorize_parent
private
def authorize_parent
authorize! :read, (@event || @project)
end