I have an issue with a dynamic active admin scope. I am attempting to create a scope for each "manager" of a "project" in my app. However, the scopes don't seem to update when a new manager is created (or assigned to a project) but they DO update if I restart the server. So the code "works" per se but obviously not in the way I would like it to. I'm a ruby/rails noob so I am not sure if I need to do something to "refresh" the scope in some way.
As an FYI, I am using Rails 3.2 on Heroku Cedar with ActiveAdmin
Here is the code in question (that works but only brings in new managers after the server is restarted):
Manager.find_each do |m|
scope m.first_name do |projects|
projects.where(:manager_id => m.id)
end
end
And the entire Active Admin Project model:
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
Here is an actual solution to this problem ... Altho using filters instead is more desirable stability and maintenance wise, this looks nicer in ActiveAdmin and is more user friendly since scopes become nice looking tabs.
It is a bit of a hack, but it is a viable solution where appropriate:
The trick is to update the scopes in a before_filter on the controllers index action.
This could get bad if you have many scopes created on a resource (altho you can easily set some limits)
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
I found this to work for me:
ActiveAdmin file
scope :working, :default => true do |projects|
Project.working
end
Model
scope :working, -> { where(:status => 'working') }
A bit late in the reply but hopefully it helps someone out.
True dynamic scopes inside the AA register blocks won't work. With that I mean that changes in the Manager table won't be reflected in the at 'initialization'-time created dynamic scopes. Also see: https://github.com/gregbell/active_admin/wiki/Creating-dynamic-scopes. What you could try is using filters instead of scopes. Then you can write something like:
filter :managers, :as => :select, :collection => proc { Manager.order('name ASC').map(&:first_name) }
and changes in the managers properties will show (after page refresh) without restarting the server. Also check https://github.com/gregbell/active_admin/issues/1261#issuecomment-5296549
Also note that active record scopes are !different! from active admin scopes. you might want to check
http://apidock.com/rails/ActiveRecord/NamedScope/ClassMethods/scope
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With