簡體   English   中英

Ruby on Rails-Pundit-控制器的未知操作

[英]Ruby on Rails - pundit - unknown action for controller

這個問題是指這個特定的問題。

我使用pundit作為我的授權gem,我希望用戶X只能下載屬於用戶X的用戶信息。現在我將http:// localhost:3000 / download.csv作為我接收用戶信息的鏈接。 但是,如果我登錄到另一個用戶(例如user / 2),則仍然可以輸入url並下載user / 3數據。

我現在所擁有的:

user_policy.rb

class UserPolicy < ApplicationPolicy

  def profile?
    true
  end

  def download?

  end

  private

  def user_or_admin
    user.id == record.id || user.admin?
  end


end

application_policy.rb

class ApplicationPolicy
  attr_reader :user, :record

  def initialize(user, record)
    @user = user
    @record = record
  end

  def index?
    false
  end

  def show?
    scope.where(:id => record.id).exists?
  end

  def create?
    create?
  end

  def new?
    create?
  end

  def update?
    false
  end

  def edit?
    update?
  end

  def destroy?
    false
  end

  class Scope
    attr_reader :user, :scope

    def initialize(user, scope)
      @user = user
      @scope = scope
    end

    def resolve
      scope.all
    end
  end
end

這是我的user_controller.rb#這不是users_controller,那些是不同的視圖

    class UserController < ApplicationController
  prepend_view_path(File.join(Rails.root, 'app/views/user/'))


  layout 'application'


  def index

  end

  def billing
  end

  def plan
  end

  def profile
    @user = User.find(params[:id])
    @user_posts = @user.posts.order('created_at DESC')
  end
end

def download
  @user = User.find(params[:id])

  respond_to do |format|
    format.html
    format.csv { send_data @user.csv, filename: "userinfo-#{Date.today}.csv" }
  end
end

  def support
    @user = User.find(params[:id])
    @user_posts = @user.posts.order('created_at DESC')
  end

  def notifications
  end

  def show
    @user = User.find(params[:id])
    @posts = current_user.posts.order('created_at DESC')
    @user_posts = @user.posts.order('created_at DESC')
  end

更新:按照建議,我嘗試在user_controller中實施新的下載操作,並嘗試在我的視圖中使用以下代碼:

<p><%= link_to("Export data as CSV", download_path(@user, format: :csv), { :controller => :user, :action => :download }, class: "btn btn-success") %></p> 

但這會引發以下錯誤:

接收未知動作-找不到UserController的“下載”動作

routes.rb

        Rails.application.routes.draw do

  get 'legal/privacy'

  get :datenschutz, to: 'legal#terms_of_service'


  devise_for :users, path_names: { sign_in: 'login', sign_out: 'logout', sign_up: 'registrieren', edit: 'bearbeiten' }, :controllers => { registrations: 'registrations' }

  get '/users/mitteilungen/:id' => 'user#notifications'
  get '/users/:id/artikel/', :to => 'user#support', :as => :artikel
  get '/users/plan' => 'user#plan'
  get '/users/billing' => 'user#billing'
  get '/users/:id', :to => 'user#profile', :as => :user
  get 'download', :to => 'user#download', :controller => :user, action: :download, :as => :download


  resources :posts, path: :news do
    resources :comments, path: :kommentare do
    end
  end


  devise_scope :user do
    resources :posts, path: :news do
      resources :comments do

      end
    end
  end
  root to: "posts#index", as: :root

end

您的條件錯誤@user.id = user.id

user IS @user 我認為您的意思是user.id = record.id

record是您正在授權的實例,例如:

def show
  @user = User.find(params[:id])
  authorize @user
  ...
end

authorize @user基本上是以下用戶的快捷方式: UserPolicy.new(@user, current_user).show?

順便說一句,我不確定,但我認為您可以放心地忽略.iduser == record

UPD。 我重新閱讀了您的政策。 ApplicationPolicy通常如下所示:

class ApplicationPolicy
  attr_reader :user, :record

  def initialize(user, record)
    @user = user
    @record = record
  end
end

您重寫了構造函數。 為什么? 讓它保持Pundit預期的樣子

UPD2。 我希望您的UserPolicy如下所示:

class UserPolicy < ApplicationPolicy
  def profile? #this is the action I have the button in to export data
    return true if user_or_admin?
  end

  private

  def user_or_admin?
    user.id == record.id || user.admin?
  end
end

我們對我的原始答案的評論討論過多。 我想澄清我的觀點。

你寫了:

我使用pundit作為我的授權gem,我希望用戶X只能下載屬於用戶X的userdata。現在我將http:// localhost:3000 / download / x.csv作為我接收用戶的鏈接數據。 但是,如果我登錄到另一個用戶,例如user /:id 2,我仍然可以輸入url並下載users / 3數據。

因此,問題在於授權不起作用。 我對嗎?

之后,您寫道:

更新:按照建議,我嘗試在user_controller中實施新的下載操作,並嘗試在我的視圖中使用此代碼:...

但這會引發以下錯誤:...

因此,您的路由問題不在原始問題范圍內,應在另一個問題中解決。 無論如何,您可以查看此問題

所以。 如果您的問題是授權-只需正確編寫策略,然后在控制器中使用它們即可。 這就是全部。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM