相关模型的每个实例的活动管理范围

我有动态主动管理范围的问题。 我试图在我的应用程序中为“项目”的每个“经理”创建一个范围。 但是,在创建(或分配给项目)新管理器时,范围似乎不会更新,但如果我重新启动服务器,它们会更新。 所以代码本身“有效”,但显然不是我想要的方式。 我是ruby / rails noob所以我不确定我是否需要做某些事情以某种方式“刷新”范围。

作为一个FYI,我在Heroku Cedar上使用Rails 3.2和ActiveAdmin

这是有问题的代码(可以工作,但只在服务器重新启动后引入新的管理器):


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 

以下是此问题的实际解决方案……使用filter代替更理想的稳定性和维护性,这在ActiveAdmin中看起来更好,并且由于范围变得很好看,因此更加用户友好。

这有点像黑客攻击,但在适当的情况下它是一个可行的解决方案:

诀窍是更新控制器索引操作的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 

我发现这对我有用:

ActiveAdmin文件

 scope :working, :default => true do |projects| Project.working end 

模型

 scope :working, -> { where(:status => 'working') } 

回复有点晚,但希望它可以帮助别人。

AA寄存器块内的真实动态范围将不起作用。 我的意思是Manager表中的更改不会反映在’初始化’时创建的动态范围中。 另请参阅: https : //github.com/gregbell/active_admin/wiki/Creating-dynamic-scopes 。 您可以尝试使用filter而不是范围。 然后你可以这样写:

 filter :managers, :as => :select, :collection => proc { Manager.order('name ASC').map(&:first_name) } 

管理器属性中的更改将显示(页面刷新后),而不重新启动服务器。 另请查看https://github.com/gregbell/active_admin/issues/1261#issuecomment-5296549

另请注意,活动记录范围是不同的! 来自活动管理范围。 你可能想检查一下

http://apidock.com/rails/ActiveRecord/NamedScope/ClassMethods/scope

Rails只在生产模式下加载一次类。 这意味着您的范围只被调用一次然后被缓存。 这就是为什么新的作用域在重新启动之后才会显示的原因。 如果您在案例中编辑了经理的名字,情况也是如此。

我认为解决方案可能是使用lambda或Proc,但在我玩的几分钟内,我没有成功。 它也可能无法以activeadmin的方式编写。