【问题标题】:Nested resource id mix-up in member_actionmember_action 中的嵌套资源 ID 混淆
【发布时间】:2019-12-29 21:00:24
【问题描述】:

我在 SupportSession 资源“显示”页面上有一个 action_item。请注意,此特定资源嵌套在 SupportAllocation 下:

ActiveAdmin.register SupportSession do
  belongs_to :support_allocation

这是嵌套 SupportSession 资源的 action_item 代码:​​

  action_item :request_approval, only: :show do
    link_to 'Send to service user', request_approval_support_allocation_support_session_path(resource), method: :patch
  end

以及对应的member_action代码:

  member_action :request_approval, method: :patch do
    # These commented lines all throw the same error described below
    #raise support_allocation.support_session
    #resource.status = "awaiting_approval"
    #resource.save
    #ServiceUserMailer.send_session_approval_request_email(resource).deliver_now
    redirect_to support_allocation_support_session_path, notice: "Session sent to service user for approval"
  end

action_item 按钮在“显示”页面上正确呈现并成功调用 member_action,但是当发生这种情况时,嵌套资源的 id (SupportSession id) 及其父级 (SupportAllocation) 似乎混淆了,导致以下异常错误:

ActiveRecord::RecordNotFound in SupportSessionsController#show
Couldn't find SupportSession with 'id'=9 [WHERE `support_sessions`.`support_allocation_id` = ?]

有趣的是,在浏览器地址栏中,URL 现在是:

http://localhost:3000/support_allocations/9/support_sessions/9

这反映在捕获的异常上显示的参数中:

Request
Parameters:

{"_method"=>"patch", "authenticity_token"=>"bZvr+kEThv/uri2E/zL/OWkndFmiQ+7FcGMD6fY3EQrh6d0vNqUaNvc0tC9BJliUYAyF4lxV+8/4T24YxQWzNg==", "support_allocation_id"=>"9", "id"=>"9"}

这表明 support_session (9) 的 id 已与 support_allocation_id 混淆(在此特定情况下应为 6)。因此,该方法/关联将不起作用,因为我的数据库中不存在 support_allocation_id = 9。

如果我跑步:

raise resource.inspect

在我的 action_item 中,在调用 member_action 之前,该对象看起来是正确的:

#<SupportSession id: 9, venue: "Cafe", start_time: "2019-05-15 16:12:00", end_time: "2019-05-15 16:35:00", status: "unapproved", created_at: "2019-08-23 09:11:05", updated_at: "2019-08-23 09:11:05", support_allocation_id: 6>

任何想法为什么 member_action 没有得到正确的数据并抛出上面的错误?这与它是嵌套资源有关吗?

供您参考,SupportSession 和 SupportAllocation 之间的这种关联反映在我的模型中:

class SupportAllocation < ApplicationRecord
  has_many :support_sessions

class SupportSession < ApplicationRecord
  belongs_to :support_allocation

这是 rails 路线的输出:

request_approval_support_allocation_support_session PATCH      /support_allocations/:support_allocation_id/support_sessions/:id/request_approval(.:format) support_sessions#request_approval
   batch_action_support_allocation_support_sessions POST       /support_allocations/:support_allocation_id/support_sessions/batch_action(.:format)         support_sessions#batch_action
                support_allocation_support_sessions GET        /support_allocations/:support_allocation_id/support_sessions(.:format)                      support_sessions#index
                                                    POST       /support_allocations/:support_allocation_id/support_sessions(.:format)                      support_sessions#create
             new_support_allocation_support_session GET        /support_allocations/:support_allocation_id/support_sessions/new(.:format)                  support_sessions#new
            edit_support_allocation_support_session GET        /support_allocations/:support_allocation_id/support_sessions/:id/edit(.:format)             support_sessions#edit
                 support_allocation_support_session GET        /support_allocations/:support_allocation_id/support_sessions/:id(.:format)                  support_sessions#show
                                                    PATCH      /support_allocations/:support_allocation_id/support_sessions/:id(.:format)                  support_sessions#update
                                                    PUT        /support_allocations/:support_allocation_id/support_sessions/:id(.:format)                  support_sessions#update
                                                    DELETE     /support_allocations/:support_allocation_id/support_sessions/:id(.:format)                  support_sessions#destroy

【问题讨论】:

    标签: ruby-on-rails ruby ruby-on-rails-5 activeadmin


    【解决方案1】:

    我设法解决了这个问题,尽管我从来没有弄清楚为什么两个 id(SupportSession 和 SupportAllocation)会混淆。

    我的解决方案是将此代码用于 action_item:

      action_item :send_approval, only: :show, if: proc { support_session.status == 'unapproved' || support_session.status == 'awaiting_approval'} do
        link_to 'Send to service user', send_approval_support_allocation_support_session_path(id: support_session.id, support_allocation_id: support_session.support_allocation.id), method: :patch
      end
    

    以及 member_action 的代码:

      member_action :send_approval, method: :patch do
        ServiceUserMailer.send_session_approval_request_email(resource).deliver_now
        resource.status = 'awaiting_approval'
        resource.save
        redirect_to support_allocation_support_session_path, notice: "Session sent to service user for approval"
      end
    

    此外,CanCanCan 授权似乎存在一些问题,这可能无关但值得一提。我在 SupportSession 上向当前用户授予了读取/创建/更新权限,但这些方法似乎只有在我授予“管理”权限时才有效。然后我不得不撤销 Ability.rb 中的“销毁”权限:

      can :manage, SupportSession, support_allocation: { support_worker: {id: user.id }}, status: 'unapproved'
      can :manage, SupportSession, support_allocation: { support_worker: {id: user.id }}, status: 'awaiting_approval'
      cannot :destroy, SupportSession
    

    希望对某人有所帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-02-08
      • 2015-09-21
      • 2014-05-30
      • 1970-01-01
      • 1970-01-01
      • 2011-08-05
      相关资源
      最近更新 更多