簡體   English   中英

Rails 4-Pundit-如何編寫示波器

[英]Rails 4 - Pundit - how to write a scope

我正在嘗試學習如何在Rails 4中使用Pundit。在過去的兩年中,我一直在嘗試學習這一點,並且正在緩慢地取得一點進展。

我也在嘗試學習如何編寫范圍。 我仍在嘗試找出如何將建議翻譯成簡單的英語,以便我可以開始理解。

我陷入了權威策略使用的范圍和我可以在模型中編寫的通用范圍類的交集。

我有Uer,Profile和Project的模型。

關聯是:

用戶

has_one :profile

輪廓

belongs_to :user
has_many :projects

項目

belongs_to :profile

我正在嘗試編寫一個專家政策,允許不同的用戶查看不同的項目。 我正在編寫范圍內的策略,以進行管理。

在我的項目模型中,我正在嘗試編寫范圍,以查找用戶的所有項目。 用簡單的英語來說,我想在所有項目中搜索那些概要文件ID屬於與當前用戶相等的用戶ID的項目。

在我的權威政策中,我試圖編寫以下解決方法:

class Scope
    attr_reader :user, :scope

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

    def resolve
      if user.has_role?(:admin)
        scope.all
      elsif user.id == @project.profile.user_id
        scope.projects_for_user 
      elsif user.present?
        scope.in_state(:publish)
      else 
        Project.none  
      end
    end
  end

我嘗試了大約100種不同的方法來嘗試在我的項目模型中編寫一個范圍,以查找屬於當前用戶的項目。 我知道我無法在模型中使用devise的current_user,因此無法在范圍內使用它。 這兩個是我的最佳嘗試-都錯了。

scope :projects_for_user, -> { joins(:user_id).where('project.profile.user_id = ?', user.id) }

scope :projects_for_user, -> { where(project.profile.user_id: User.id) }

我學習這本書的主要問題是我看不到如何將這條線分解為不同的部分。

據我所知,“:”之前的內容是您要尋找的東西。 運行范圍時,“:”后面的位是您正在使用的實例。 如果是正確的話,那么我就對為什么我的第二次嘗試不起作用感到困惑(並且對於第一次嘗試中的joins語句也很困惑)。

如果有人可以用簡單的英文解釋如何編寫范圍,我相信我知道我要尋找的東西,只是極度迷失了如何編寫查詢來查找范圍。

當前,當我嘗試使用我的項目策略時(我嘗試在下面合並Taryn的建議-盡管我不了解范圍的每個組成部分,所以我不確定它是怎么回事)。

class ProjectPolicy < ApplicationPolicy

  attr_reader :user, :record

  class Scope
    attr_reader :user, :scope

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

    def resolve
      if user.has_role?(:admin)
        scope.all
      elsif user.id == @project.profile.user_id
        scope.projects_for_user(user)  
      elsif user.present?
        scope.in_state(:publish)
      else 
        Project.none  
      end
    end
  end


  def index?
    true
  end

  def show?
    true
  end

private
  def project
    record
  end

項目模型:

scope :projects_for_user, -> (user){ joins(:user_id).where('project.profile.user_id = ?', user.id) }

在我的項目負責人中,我有:

class ProjectsController < ApplicationController

  before_action :set_project, only: [:show, :edit, :update, :destroy ]
  before_action :authenticate_user!

  def index
    @projects = Project.all
    authorize @projects
  end

  def show
    @project = Project.find(params[:id])
    # authorize @project

  end

private
    def set_project
      @project = Project.find(params[:id])
      authorize @project
    end

當我保存並嘗試時,出現錯誤提示:

wrong number of arguments (given 2, expected 0)

當我嘗試查看項目索引或特定項目時返回此錯誤(因此,我認為這與范圍無關)。 我不知道給出了兩個參數來知道如何解決這個問題。

添加堆棧跟蹤

ArgumentError - wrong number of arguments (given 2, expected 0):
  pundit (1.1.0) lib/pundit.rb:112:in `policy!'
  pundit (1.1.0) lib/pundit.rb:235:in `policy'
  pundit (1.1.0) lib/pundit.rb:194:in `authorize'
  app/controllers/eois_controller.rb:20:in `show'
  actionpack (4.2.4) lib/action_controller/metal/implicit_render.rb:4:in `send_action'
  actionpack (4.2.4) lib/abstract_controller/base.rb:198:in `process_action'
  actionpack (4.2.4) lib/action_controller/metal/rendering.rb:10:in `process_action'
  actionpack (4.2.4) lib/abstract_controller/callbacks.rb:20:in `block in process_action'
  activesupport (4.2.4) lib/active_support/callbacks.rb:117:in `call'
  activesupport (4.2.4) lib/active_support/callbacks.rb:555:in `block (2 levels) in compile'
  activesupport (4.2.4) lib/active_support/callbacks.rb:505:in `call'
  activesupport (4.2.4) lib/active_support/callbacks.rb:92:in `__run_callbacks__'
  activesupport (4.2.4) lib/active_support/callbacks.rb:778:in `_run_process_action_callbacks'
  activesupport (4.2.4) lib/active_support/callbacks.rb:81:in `run_callbacks'
  actionpack (4.2.4) lib/abstract_controller/callbacks.rb:19:in `process_action'
  actionpack (4.2.4) lib/action_controller/metal/rescue.rb:29:in `process_action'
  actionpack (4.2.4) lib/action_controller/metal/instrumentation.rb:32:in `block in process_action'
  activesupport (4.2.4) lib/active_support/notifications.rb:164:in `block in instrument'
  activesupport (4.2.4) lib/active_support/notifications/instrumenter.rb:20:in `instrument'
  activesupport (4.2.4) lib/active_support/notifications.rb:164:in `instrument'
  actionpack (4.2.4) lib/action_controller/metal/instrumentation.rb:30:in `process_action'
  actionpack (4.2.4) lib/action_controller/metal/params_wrapper.rb:250:in `process_action'
  searchkick (1.3.0) lib/searchkick/logging.rb:153:in `process_action'
  activerecord (4.2.4) lib/active_record/railties/controller_runtime.rb:18:in `process_action'
  actionpack (4.2.4) lib/abstract_controller/base.rb:137:in `process'
  actionview (4.2.4) lib/action_view/rendering.rb:30:in `process'
  actionpack (4.2.4) lib/action_controller/metal.rb:196:in `dispatch'
  actionpack (4.2.4) lib/action_controller/metal/rack_delegation.rb:13:in `dispatch'
  actionpack (4.2.4) lib/action_controller/metal.rb:237:in `block in action'
  actionpack (4.2.4) lib/action_dispatch/routing/route_set.rb:76:in `dispatch'
  actionpack (4.2.4) lib/action_dispatch/routing/route_set.rb:45:in `serve'
  actionpack (4.2.4) lib/action_dispatch/journey/router.rb:43:in `block in serve'
  actionpack (4.2.4) lib/action_dispatch/journey/router.rb:30:in `serve'
  actionpack (4.2.4) lib/action_dispatch/routing/route_set.rb:821:in `call'
  omniauth (1.3.1) lib/omniauth/strategy.rb:186:in `call!'
  omniauth (1.3.1) lib/omniauth/strategy.rb:164:in `call'
  omniauth (1.3.1) lib/omniauth/strategy.rb:186:in `call!'
  omniauth (1.3.1) lib/omniauth/strategy.rb:164:in `call'
  omniauth (1.3.1) lib/omniauth/strategy.rb:186:in `call!'
  omniauth (1.3.1) lib/omniauth/strategy.rb:164:in `call'
  omniauth (1.3.1) lib/omniauth/strategy.rb:186:in `call!'
  omniauth (1.3.1) lib/omniauth/strategy.rb:164:in `call'
  meta_request (0.4.0) lib/meta_request/middlewares/app_request_handler.rb:13:in `call'
  meta_request (0.4.0) lib/meta_request/middlewares/meta_request_handler.rb:13:in `call'
  warden (1.2.6) lib/warden/manager.rb:35:in `block in call'
  warden (1.2.6) lib/warden/manager.rb:34:in `call'
  rack (1.6.4) lib/rack/etag.rb:24:in `call'
  rack (1.6.4) lib/rack/conditionalget.rb:25:in `call'
  rack (1.6.4) lib/rack/head.rb:13:in `call'
  actionpack (4.2.4) lib/action_dispatch/middleware/params_parser.rb:27:in `call'
  actionpack (4.2.4) lib/action_dispatch/middleware/flash.rb:260:in `call'
  rack (1.6.4) lib/rack/session/abstract/id.rb:225:in `context'
  rack (1.6.4) lib/rack/session/abstract/id.rb:220:in `call'
  actionpack (4.2.4) lib/action_dispatch/middleware/cookies.rb:560:in `call'
  activerecord (4.2.4) lib/active_record/query_cache.rb:36:in `call'
  activerecord (4.2.4) lib/active_record/connection_adapters/abstract/connection_pool.rb:653:in `call'
  activerecord (4.2.4) lib/active_record/migration.rb:377:in `call'
  actionpack (4.2.4) lib/action_dispatch/middleware/callbacks.rb:29:in `block in call'
  activesupport (4.2.4) lib/active_support/callbacks.rb:88:in `__run_callbacks__'
  activesupport (4.2.4) lib/active_support/callbacks.rb:778:in `_run_call_callbacks'
  activesupport (4.2.4) lib/active_support/callbacks.rb:81:in `run_callbacks'
  actionpack (4.2.4) lib/action_dispatch/middleware/callbacks.rb:27:in `call'
  actionpack (4.2.4) lib/action_dispatch/middleware/reloader.rb:73:in `call'
  actionpack (4.2.4) lib/action_dispatch/middleware/remote_ip.rb:78:in `call'
  better_errors (2.1.1) lib/better_errors/middleware.rb:84:in `protected_app_call'
  better_errors (2.1.1) lib/better_errors/middleware.rb:79:in `better_errors_call'
  better_errors (2.1.1) lib/better_errors/middleware.rb:57:in `call'
  actionpack (4.2.4) lib/action_dispatch/middleware/debug_exceptions.rb:17:in `call'
  rack-contrib (1.4.0) lib/rack/contrib/response_headers.rb:17:in `call'
  meta_request (0.4.0) lib/meta_request/middlewares/headers.rb:16:in `call'
  web-console (2.3.0) lib/web_console/middleware.rb:28:in `block in call'
  web-console (2.3.0) lib/web_console/middleware.rb:18:in `call'
  actionpack (4.2.4) lib/action_dispatch/middleware/show_exceptions.rb:30:in `call'
  railties (4.2.4) lib/rails/rack/logger.rb:38:in `call_app'
  railties (4.2.4) lib/rails/rack/logger.rb:20:in `block in call'
  activesupport (4.2.4) lib/active_support/tagged_logging.rb:68:in `block in tagged'
  activesupport (4.2.4) lib/active_support/tagged_logging.rb:26:in `tagged'
  activesupport (4.2.4) lib/active_support/tagged_logging.rb:68:in `tagged'
  railties (4.2.4) lib/rails/rack/logger.rb:20:in `call'
  request_store (1.3.1) lib/request_store/middleware.rb:9:in `call'
  actionpack (4.2.4) lib/action_dispatch/middleware/request_id.rb:21:in `call'
  rack (1.6.4) lib/rack/methodoverride.rb:22:in `call'
  rack (1.6.4) lib/rack/runtime.rb:18:in `call'
  activesupport (4.2.4) lib/active_support/cache/strategy/local_cache_middleware.rb:28:in `call'
  rack (1.6.4) lib/rack/lock.rb:17:in `call'
  actionpack (4.2.4) lib/action_dispatch/middleware/static.rb:116:in `call'
  rack (1.6.4) lib/rack/sendfile.rb:113:in `call'
  skylight (0.10.6) lib/skylight/middleware.rb:61:in `call'
  railties (4.2.4) lib/rails/engine.rb:518:in `call'
  railties (4.2.4) lib/rails/application.rb:165:in `call'
  rack (1.6.4) lib/rack/content_length.rb:15:in `call'
  puma (3.4.0) lib/puma/configuration.rb:224:in `call'
  puma (3.4.0) lib/puma/server.rb:569:in `handle_request'
  puma (3.4.0) lib/puma/server.rb:406:in `process_client'
  puma (3.4.0) lib/puma/server.rb:271:in `block in run'
  puma (3.4.0) lib/puma/thread_pool.rb:114:in `block in spawn_thread'

在2016-09-08 13:23:01 +1000上為:: 1開始發布POST“ / __ better_errors / 123578515c1e4e10 / variables”

堆棧跟蹤分析

我自己寫的唯一一行是eois控制器(在show action內部)中的authorize @eoi行。 這是使用專家的關鍵部分。 堆棧跟蹤的其余部分來自我未編寫且不知道如何更改的內容。

 app/controllers/eois_controller.rb:20:in `show'

對可能的重復標簽的響應

我也張貼了另一個問題。 他們將去不同的地方。 在這篇文章中,我認為我可能是在將范圍寫入錯誤(我可能曾經寫過)。 在另一篇文章中,我嘗試列出了整個過程,以查看是否有人能夠幫助我了解我要去哪里。

問題是您實際上沒有為范圍提供用戶ID。 在這個例子中: User.id永遠不會起作用... User類代表所有用戶...詢問ID是沒有任何意義的(您只需獲取ruby的ID,存儲類方法的對象)。

在另一個...中,您使用user.id但實際上並未設置user變量的值(因此它將始終失敗)。

也許嘗試實際將相關的用戶ID作為參數傳遞給方法,例如:

# define the `user` parameter as an argument to this scope-method
scope :projects_for_user, -> (user){ joins(:user_id).where('project.profile.user_id = ?', user.id) }

def resolve
  if user.has_role?(:admin)
    scope.all
  elsif user.id == @project.profile.user_id
    scope.projects_for_user(user) # pass the user into the method
  elsif user.present?
    scope.in_state(:publish)
  else 
    Project.none  
  end
end

注意:我還沒有(也不會)測試此代碼,它可能有錯別字或錯誤……試一試並修復錯誤。

暫無
暫無

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

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