我有一个动态的事件管理范围问题。我正在尝试为我的应用程序中的“项目”的每个“经理”创建一个范围。但是,创建新管理器(或将其分配给项目)时,作用域似乎并没有更新,但是如果我重新启动服务器,它们确实会更新。因此,代码本身就可以“运行”,但显然不是我想要的那样。我是一个 ruby /铁路新手,所以我不确定是否需要做一些事情以某种方式“刷新”示波器。
仅供引用,我在带有ActiveAdmin的Heroku Cedar上使用Rails 3.2
这是有问题的代码(可以工作,但仅在服务器重新启动后才引入新的管理器):
Manager.find_each do |m|
scope m.first_name do |projects|
projects.where(:manager_id => m.id)
end
end
以及整个Active Admin Project模型:
ActiveAdmin.register Project do
menu :priority => 1
index do
column :name
column :company_name
column :status
column :projection do |project|
number_to_currency project.projection
end
column :updated_at
default_actions
end
scope :all
scope :working, :default => true do |projects|
projects.where(:status => 'working')
end
Manager.find_each do |m|
scope m.first_name do |projects|
projects.where(:manager_id => m.id)
end
end
end
最佳答案
这是解决此问题的一种实际解决方案。使用过滤器替代更希望获得稳定性和维护性,这在ActiveAdmin中看起来更好,并且用户使用起来更加友好,因为作用域变成了漂亮的选项卡。
这有点骇人听闻,但在适当的情况下是可行的解决方案:
技巧是在 Controller 索引操作上的before_filter中更新作用域。
如果您在资源上创建了多个作用域,这可能会变得很糟(尽管您可以轻松设置一些限制)
ActiveAdmin.register Project do
menu :priority => 1
index do
column :name
column :company_name
column :status
column :projection do |project|
number_to_currency project.projection
end
column :updated_at
default_actions
end
scope :all
scope :working, :default => true do |projects|
projects.where(:status => 'working')
end
controller do
before_filter :update_scopes, :only => :index
def update_scopes
resource = active_admin_config
Manager.all.each do |m|
next if resource.scopes.any? { |scope| scope.name == m.first_name }
resource.scopes << (ActiveAdmin::Scope.new m.first_name do |projects|
projects.where(:manager_id => m.id)
end)
end
# try something like this for deletions (untested)
resource.scopes.delete_if do |scope|
!(Manager.all.any? { |m| scope.name == m.first_name } || ['all', 'working'].include?(scope.name)) # don't delete other scopes you have defined
end
end
end
end