2

我有以下型号:

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:是父对象。

4

1 回答 1

1

看看维基文章。有一个关于多态类型的部分。您需要使用嵌套授权。这是相关部分:

假设可以通过多态关联将任务分配给项目或事件。可以将数组传递给 :through 选项,它将使用它找到的第一个。

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
于 2013-01-09T21:05:41.183 回答