Ruby on rails Rails/CanCan允许更新CarrierWave附件的单个属性

Ruby on rails Rails/CanCan允许更新CarrierWave附件的单个属性,ruby-on-rails,ruby,carrierwave,cancan,Ruby On Rails,Ruby,Carrierwave,Cancan,在我的Rails应用程序中,我有一个客户端模型,有很多:客户端附件。我希望非管理员用户能够创建附件,但我不希望他们更新客户端的其他属性 我使用CanCan进行角色授权,使用CarrierWave进行附件 目前我正在做: 在models/client.rb中: class Client < ApplicationRecord has_many :client_attachments accepts_nested_attributes_for :client_attachments,

在我的Rails应用程序中,我有一个
客户端
模型,
有很多:客户端附件
。我希望非管理员用户能够创建附件,但我不希望他们更新
客户端的其他属性

我使用
CanCan
进行角色授权,使用
CarrierWave
进行附件

目前我正在做:

models/client.rb
中:

class Client < ApplicationRecord
  has_many :client_attachments
  accepts_nested_attributes_for :client_attachments, allow_destroy: true
end
class ClientAttachment < ApplicationRecord
  mount_uploader :file, ClientAttachmentUploader
  belongs_to :client
end
can [:update], Client
can [:create, :update, :destroy], ClientAttachment, :user_id => user.id
private
  def client_params
    if current_user.admin?
        params.require(:client).permit(:name, :address, :etc, 
          client_attachments_attributes: [:id, :client_id, :file, :user_id])
    elsif current_user.user?
        params.require(:client).permit(client_attachments_attributes: [:id, :client_id, :file, :user_id])
    end
  end
能力.rb中

class Client < ApplicationRecord
  has_many :client_attachments
  accepts_nested_attributes_for :client_attachments, allow_destroy: true
end
class ClientAttachment < ApplicationRecord
  mount_uploader :file, ClientAttachmentUploader
  belongs_to :client
end
can [:update], Client
can [:create, :update, :destroy], ClientAttachment, :user_id => user.id
private
  def client_params
    if current_user.admin?
        params.require(:client).permit(:name, :address, :etc, 
          client_attachments_attributes: [:id, :client_id, :file, :user_id])
    elsif current_user.user?
        params.require(:client).permit(client_attachments_attributes: [:id, :client_id, :file, :user_id])
    end
  end
客户机\u控制器.rb
中:

class Client < ApplicationRecord
  has_many :client_attachments
  accepts_nested_attributes_for :client_attachments, allow_destroy: true
end
class ClientAttachment < ApplicationRecord
  mount_uploader :file, ClientAttachmentUploader
  belongs_to :client
end
can [:update], Client
can [:create, :update, :destroy], ClientAttachment, :user_id => user.id
private
  def client_params
    if current_user.admin?
        params.require(:client).permit(:name, :address, :etc, 
          client_attachments_attributes: [:id, :client_id, :file, :user_id])
    elsif current_user.user?
        params.require(:client).permit(client_attachments_attributes: [:id, :client_id, :file, :user_id])
    end
  end
因此,实际上是客户端控制器允许非管理员用户只更新客户端所有属性中的附件

这种方法让我感到困扰,因为它不能很好地处理视图。在我的
中,对于非管理员用户来说,它看起来像是可以编辑客户端,而实际上他只能编辑附件


有什么更好的方法吗?

cancan最棒的一点是,你可以(可以)对对象的任何操作授予权限,你可以创建一个新的“操作”,专门用于上传附件
:upload_attachment
,授予管理员对
上传附件
编辑附件
的权限,而非管理员只能
上传附件
。您必须在控制器上使用自定义授权操作,但这是可以做到的。感谢您为我指明了正确的方向!我正在尝试
授权!:上传附件,@client if params[:client_attachments]
但它不工作,可能是因为控制器顶部的
加载和授权资源
覆盖了它。有什么提示吗?您需要跳过控制器操作的授权,然后调用
authorize:在控制器操作中上载附件和编辑。您可以执行以下操作:
skip\u authorize\u resource only::edit
为此,cancan的一大优点是您可以(可以)对对象上的任何操作授予权限,您可以创建一个新的“操作”,该操作特定于上载附件
:upload\u attachment
,授予管理员对
上传附件
编辑附件
的权限,而非管理员只能
上传附件
。您必须在控制器上使用自定义授权操作,但这是可以做到的。感谢您为我指明了正确的方向!我正在尝试
授权!:上传附件,@client if params[:client_attachments]
但它不工作,可能是因为控制器顶部的
加载和授权资源
覆盖了它。有什么提示吗?您需要跳过控制器操作的授权,然后调用
authorize:在控制器操作中上载附件和编辑。您可以为此执行
skip\u authorize\u resource only::edit