具有 2 深度关联的嵌套资源
Nested resource with 2-deep association
我正在尝试设置活动管理员,以便 AdminUser(已登录)可以查看分配给他们的所有 ServiceUser 的列表,然后单击特定 ServiceUser 旁边的 link 以查看所有支持他们创建的会话(针对特定的 ServiceUser)。
型号:
class ServiceUser
has_many :support_allocations
has_many :admin_users, through: :support_allocations
has_many :support_budgets
class AdminUser < ApplicationRecord
has_many :support_allocations
has_many :service_users, through: :support_allocations
class SupportAllocation < ApplicationRecord
belongs_to :admin_user
belongs_to :service_user
has_many :support_sessions
class SupportSession < ApplicationRecord
belongs_to :invoice, optional: true
belongs_to :support_allocation
has_one :service_user, through: :support_allocation
has_one :admin_user, through: :support_allocation
我猜我需要让 SupportSessions 成为 ServiceUser 的嵌套资源,这样我就可以遵循 restful 原则(即使用通往 /service_users/1/support_sessions 的路线)。我设法像这样嵌套资源:
ActiveAdmin.register SupportSession do
belongs_to :service_user
但我意识到省略了关键的连接 table SupportAllocation。而且,它不起作用!错误信息是:
NoMethodError in SupportSessionsController#index
undefined method `support_sessions' for #<ServiceUser:0x00007fe6316b9030> Did you mean? support_allocations
以前我可以使用以下代码查看分配给 AdminUser 的所有 ServiceUser 的所有 SupportSession:
ActiveAdmin.register SupportSession do
super.includes(support_allocation: [:service_user, :admin_user])
这个问题是我想在 ServiceUser 和 AdminUser 之间的 SupportAllocation 关系的上下文中使用资源。因此,登录的 AdminUser 可以看到为他们分配的所有 ServiceUser 的索引列表(通过 SupportAllocation),然后移动到所选 ServiceUser 的所有 SupportSession 的索引列表(从第一个列表)。
这里的嵌套资源是正确的解决方案还是有更简单的方法来拥有一个通用的 SupportSession 资源页面,该页面可以显示所有 ServiceUser 或特定 ServiceUser 的 SupportSession(通过 'id' 在 URL)?我如何与中间人一起使用这种棘手的两级关联 table?
非常感谢您的帮助。
这是 app/admin/
中我的 support_sessions.rb 控制器的代码
ActiveAdmin.register SupportSession do
menu label: 'My sessions'
#belongs_to :support_allocation
belongs_to :service_user
# Eager loading to speed up queries
includes :service_user, :admin_user, :support_allocation
sidebar :help, priority: 0 do
"Need help? Email us at help@example.com"
end
# Default sort order
config.sort_order = 'support_sessions.date_held_asc'
controller do
def scoped_collection
#super.includes :support_allocation
super.includes(support_allocation: [:service_user, :admin_user])
#SupportSession.includes(support_allocation: [:service_user, :admin_user])
#super.includes :service_user, :admin_user
end
end
scope :all, :default => true
scope :invoiced
scope :uninvoiced
index do
selectable_column
column 'Date held', :date_held
#column 'Service user', :full_name, :sortable => 'service_users.family_name' do |ss|
#service_user = ServiceUser.find(ss.support_allocation.service_user.service_user_id).full_name
#ss.support_allocation.service_user
#end
#column 'Based at', sortable: 'support_allocation.service_user.organisation.org_name' do |ss|
#ss.support_allocation.service_user.organisation.org_name
#end
column 'Venue', :venue
#column 'Support worker', :full_name, :sortable => 'admin_users.family_name' do |ss|
#support_worker = AdminUser.find(ss.admin_user_id).full_name
#ss.support_allocation.admin_user
#end
actions
end
permit_params(:admin_user_id, :service_user_id, :venue, :mode_of_delivery, :date_held, :time_start, :time_end, :total_breaks, :status)
form do |f|
f.semantic_errors *f.object.errors.keys
f.inputs 'Support session details' do
# Code to check if creating a new record or editing an existing record:
#if f.object.new_record?
#if current_admin_user.super_admin == false
# Pre-select only current support worker (so no other choices)
#f.input :admin_user, :label => 'Support worker', as: :select, collection: AdminUser.where(super_admin: 0, #id: current_admin_user.id), include_blank: false
#else
# Otherwise list all support workers
#f.input :admin_user, :label => 'Support worker', as: :select, collection: AdminUser.where(super_admin: 0), include_blank: true, allow_blank: false
#end
#f.input :support_allocation
#f.input :service_user, :label => 'Service user', as: :select, collection: ServiceUser.all, include_blank: true, allow_blank: false
f.input :mode_of_delivery, as: :select, collection: SupportSession.mode_of_deliveries.keys, include_blank: true, allow_blank: false
f.input :venue, :label => 'Venue'
f.input :date_held, :label => 'Date held', :as => :datepicker
f.input :time_start, :label => 'Start time'
f.input :time_end, :label => 'End time'
f.input :total_breaks, :label => 'Total breaks (in minutes)', :input_html => { :value => '0' }
if current_admin_user.super_admin == false
f.input :status, as: :select, collection: SupportSession.statuses.keys, include_blank: true, allow_blank: false
end
end
f.actions
end
end
我认为您的 ActiveAdmin 注册需要以与模型中相同的方式反映出来。
例如,您有:
ActiveAdmin.register SupportSession do
belongs_to :service_user
但是您的 SupportSession
模型定义为:
class SupportSession < ApplicationRecord
...
has_one :service_user, through: :support_allocation
...
假设你的模型是正确的,ActiveAdmin注册应该也是has_one
关系。
此外,您似乎还没有完全定义模型关系。您的 ServiceUser
模型没有相应的 belongs_to
关系。
感谢您给我的模型提示。
为了解决原来的问题,我将 SupportSession ActiveAdmin 控制器嵌套在 SupportAllocation 中:
ActiveAdmin.register SupportSession do
menu label: 'My sessions'
belongs_to :support_allocation
这会在 SupportAllocation(定义 ServiceUser 和 SupportSession 之间的关系)的上下文中为 SupportSession 创建一个新的嵌套路由,让我可以直接从 SupportAllocation 创建一个 link(例如 /support_allocations/2/support_sessions)到单个 ServiceUser 的所有 SupportSession,使用通常的路径助手:
actions defaults: false do |support_allocation|
link_to 'Manage support sessions', support_allocation_support_sessions_path(support_allocation_id: support_allocation.id), class: 'member_link'
end
我正在尝试设置活动管理员,以便 AdminUser(已登录)可以查看分配给他们的所有 ServiceUser 的列表,然后单击特定 ServiceUser 旁边的 link 以查看所有支持他们创建的会话(针对特定的 ServiceUser)。
型号:
class ServiceUser
has_many :support_allocations
has_many :admin_users, through: :support_allocations
has_many :support_budgets
class AdminUser < ApplicationRecord
has_many :support_allocations
has_many :service_users, through: :support_allocations
class SupportAllocation < ApplicationRecord
belongs_to :admin_user
belongs_to :service_user
has_many :support_sessions
class SupportSession < ApplicationRecord
belongs_to :invoice, optional: true
belongs_to :support_allocation
has_one :service_user, through: :support_allocation
has_one :admin_user, through: :support_allocation
我猜我需要让 SupportSessions 成为 ServiceUser 的嵌套资源,这样我就可以遵循 restful 原则(即使用通往 /service_users/1/support_sessions 的路线)。我设法像这样嵌套资源:
ActiveAdmin.register SupportSession do
belongs_to :service_user
但我意识到省略了关键的连接 table SupportAllocation。而且,它不起作用!错误信息是:
NoMethodError in SupportSessionsController#index
undefined method `support_sessions' for #<ServiceUser:0x00007fe6316b9030> Did you mean? support_allocations
以前我可以使用以下代码查看分配给 AdminUser 的所有 ServiceUser 的所有 SupportSession:
ActiveAdmin.register SupportSession do
super.includes(support_allocation: [:service_user, :admin_user])
这个问题是我想在 ServiceUser 和 AdminUser 之间的 SupportAllocation 关系的上下文中使用资源。因此,登录的 AdminUser 可以看到为他们分配的所有 ServiceUser 的索引列表(通过 SupportAllocation),然后移动到所选 ServiceUser 的所有 SupportSession 的索引列表(从第一个列表)。
这里的嵌套资源是正确的解决方案还是有更简单的方法来拥有一个通用的 SupportSession 资源页面,该页面可以显示所有 ServiceUser 或特定 ServiceUser 的 SupportSession(通过 'id' 在 URL)?我如何与中间人一起使用这种棘手的两级关联 table?
非常感谢您的帮助。
这是 app/admin/
中我的 support_sessions.rb 控制器的代码ActiveAdmin.register SupportSession do
menu label: 'My sessions'
#belongs_to :support_allocation
belongs_to :service_user
# Eager loading to speed up queries
includes :service_user, :admin_user, :support_allocation
sidebar :help, priority: 0 do
"Need help? Email us at help@example.com"
end
# Default sort order
config.sort_order = 'support_sessions.date_held_asc'
controller do
def scoped_collection
#super.includes :support_allocation
super.includes(support_allocation: [:service_user, :admin_user])
#SupportSession.includes(support_allocation: [:service_user, :admin_user])
#super.includes :service_user, :admin_user
end
end
scope :all, :default => true
scope :invoiced
scope :uninvoiced
index do
selectable_column
column 'Date held', :date_held
#column 'Service user', :full_name, :sortable => 'service_users.family_name' do |ss|
#service_user = ServiceUser.find(ss.support_allocation.service_user.service_user_id).full_name
#ss.support_allocation.service_user
#end
#column 'Based at', sortable: 'support_allocation.service_user.organisation.org_name' do |ss|
#ss.support_allocation.service_user.organisation.org_name
#end
column 'Venue', :venue
#column 'Support worker', :full_name, :sortable => 'admin_users.family_name' do |ss|
#support_worker = AdminUser.find(ss.admin_user_id).full_name
#ss.support_allocation.admin_user
#end
actions
end
permit_params(:admin_user_id, :service_user_id, :venue, :mode_of_delivery, :date_held, :time_start, :time_end, :total_breaks, :status)
form do |f|
f.semantic_errors *f.object.errors.keys
f.inputs 'Support session details' do
# Code to check if creating a new record or editing an existing record:
#if f.object.new_record?
#if current_admin_user.super_admin == false
# Pre-select only current support worker (so no other choices)
#f.input :admin_user, :label => 'Support worker', as: :select, collection: AdminUser.where(super_admin: 0, #id: current_admin_user.id), include_blank: false
#else
# Otherwise list all support workers
#f.input :admin_user, :label => 'Support worker', as: :select, collection: AdminUser.where(super_admin: 0), include_blank: true, allow_blank: false
#end
#f.input :support_allocation
#f.input :service_user, :label => 'Service user', as: :select, collection: ServiceUser.all, include_blank: true, allow_blank: false
f.input :mode_of_delivery, as: :select, collection: SupportSession.mode_of_deliveries.keys, include_blank: true, allow_blank: false
f.input :venue, :label => 'Venue'
f.input :date_held, :label => 'Date held', :as => :datepicker
f.input :time_start, :label => 'Start time'
f.input :time_end, :label => 'End time'
f.input :total_breaks, :label => 'Total breaks (in minutes)', :input_html => { :value => '0' }
if current_admin_user.super_admin == false
f.input :status, as: :select, collection: SupportSession.statuses.keys, include_blank: true, allow_blank: false
end
end
f.actions
end
end
我认为您的 ActiveAdmin 注册需要以与模型中相同的方式反映出来。
例如,您有:
ActiveAdmin.register SupportSession do
belongs_to :service_user
但是您的 SupportSession
模型定义为:
class SupportSession < ApplicationRecord
...
has_one :service_user, through: :support_allocation
...
假设你的模型是正确的,ActiveAdmin注册应该也是has_one
关系。
此外,您似乎还没有完全定义模型关系。您的 ServiceUser
模型没有相应的 belongs_to
关系。
感谢您给我的模型提示。
为了解决原来的问题,我将 SupportSession ActiveAdmin 控制器嵌套在 SupportAllocation 中:
ActiveAdmin.register SupportSession do
menu label: 'My sessions'
belongs_to :support_allocation
这会在 SupportAllocation(定义 ServiceUser 和 SupportSession 之间的关系)的上下文中为 SupportSession 创建一个新的嵌套路由,让我可以直接从 SupportAllocation 创建一个 link(例如 /support_allocations/2/support_sessions)到单个 ServiceUser 的所有 SupportSession,使用通常的路径助手:
actions defaults: false do |support_allocation|
link_to 'Manage support sessions', support_allocation_support_sessions_path(support_allocation_id: support_allocation.id), class: 'member_link'
end