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

Sea*_*ell 8 ruby ruby-on-rails heroku activeadmin

我有动态主动管理范围的问题.我试图在我的应用程序中为"项目"的每个"经理"创建一个范围.但是,在创建(或分配给项目)新管理器时,范围似乎不会更新,但如果我重新启动服务器,它们会更新.因此代码本身"有效",但显然不是我想要的方式.我是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
Run Code Online (Sandbox Code Playgroud)

以及整个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
Run Code Online (Sandbox Code Playgroud)

Bra*_*del 12

以下是此问题的实际解决方案......使用过滤器代替更理想的稳定性和维护性,这在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
Run Code Online (Sandbox Code Playgroud)


Jar*_*red 1

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

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