Activeadmin: How to overwrite index collection or show/hide records?

Created on 18 Oct 2011  路  50Comments  路  Source: activeadmin/activeadmin

I have AdminUser and Post.

Post belongs_to AdminUser

In the index action I should show only author posts (Post.where(:admin_user_id => current_admin_user.id)).

How I can do it?

Thanks.

bug

Most helpful comment

To override the default collection and eager load association, you can either :

  • use scope_to


scope_to :association_method => :scoped do
User.includes(:role)
end

  • override action scoped_collection in the controller, allow to


controller do
def scoped_collection
User.includes(:role)
end
end

All 50 comments

write this in your admin/posts.rb

controller do
def index
@posts = current_admin_user.posts
end
end
to override the index action.

I've got error:
undefined methodbase' for nil:NilClass`

I find :scope_to method. It should help me.

The :scope_to works fine. But error on overwriting index action still real.

Bug:

controller do
  def index
    @posts = current_admin_user.posts
  end
end

get 'admin/posts'
# => undefined method `base' for nil:NilClass

I'm having similar issues. I have a tree-based model (using Ancestry gem). I'd like my :index action to show all top level records and have the ability to "click-through" to get to the children records. I do have CanCan setup but have no special "CanCan" code in the controller.

I'd like to be able to scope my collection with
@icd9s = Icd9.where(:ancestry => params[:parent_id])

I've tried the following:
controller do
def index
@icd9s = Icd9.where(:ancestry => params[:parent_id]).page(params[:page]).per(10)
end
end

This results in a "undefined method `base' for nil:NilClass" exception which I don't know is due to CanCan, Kaminari or ActiveAdmin. Note, I've tried the above with constants in place of the params[] lookups with no luck.

I've also tried to override the InheritedResources collection method like so:
controller do
def collection
@icd9s ||= Icd9.where(:ancestry => nil).page(1).per(10)
end
end

This results in the same: "undefined methodbase' for nil:NilClass"`

Any advice is appreciated, Thanks.

please give some details of Backtrace, if u can.

which version of ruby u r using?

ruby: ree-1.8.7-2011.03

controller do
  def index
    @posts = Post.all
  end
end

undefined methodnum_pages' for #`

controller do
  def index
    @posts = current_user.posts.page(1).per(2)
  end
end

undefined methodbase' for nil:NilClass`

Extracted source render renderer_for(:index)

Full trace:

activesupport (3.1.1) lib/active_support/whiny_nil.rb:48:in `method_missing'
activeadmin (0.3.2) lib/active_admin/view_helpers/filter_form_helper.rb:177:in `column_for'
activeadmin (0.3.2) lib/active_admin/view_helpers/filter_form_helper.rb:145:in `default_filter_type'
activeadmin (0.3.2) lib/active_admin/view_helpers/filter_form_helper.rb:42:in `filter'
activeadmin (0.3.2) lib/active_admin/view_helpers/filter_form_helper.rb:19:in `active_admin_filters_form_for'
activeadmin (0.3.2) lib/active_admin/view_helpers/filter_form_helper.rb:16:in `each'
activeadmin (0.3.2) lib/active_admin/view_helpers/filter_form_helper.rb:16:in `active_admin_filters_form_for'
actionpack (3.1.1) lib/action_view/helpers/capture_helper.rb:40:in `capture'
actionpack (3.1.1) lib/action_view/helpers/capture_helper.rb:187:in `with_output_buffer'
actionpack (3.1.1) lib/action_view/helpers/capture_helper.rb:40:in `capture'
actionpack (3.1.1) lib/action_view/helpers/form_helper.rb:590:in `fields_for'
actionpack (3.1.1) lib/action_view/helpers/form_helper.rb:373:in `form_for'
activeadmin (0.3.2) lib/active_admin/view_helpers/filter_form_helper.rb:15:in `active_admin_filters_form_for'
activeadmin (0.3.2) lib/active_admin/arbre/builder.rb:45:in `send'
activeadmin (0.3.2) lib/active_admin/arbre/builder.rb:45:in `method_missing'
activeadmin (0.3.2) lib/active_admin/resource/sidebars.rb:29:in `add_default_sidebar_sections'
activeadmin (0.3.2) lib/active_admin/views/components/sidebar_section.rb:19:in `instance_eval'
activeadmin (0.3.2) lib/active_admin/views/components/sidebar_section.rb:19:in `build_sidebar_content'
activeadmin (0.3.2) lib/active_admin/views/components/sidebar_section.rb:12:in `build'
activeadmin (0.3.2) lib/active_admin/arbre/builder.rb:63:in `build_tag'
activeadmin (0.3.2) lib/active_admin/arbre/builder.rb:77:in `insert_tag'
activeadmin (0.3.2) lib/active_admin/arbre/html/element.rb:13:in `sidebar_section'
activeadmin (0.3.2) lib/active_admin/views/pages/base.rb:148:in `build_sidebar'
activeadmin (0.3.2) lib/active_admin/views/pages/base.rb:147:in `collect'
activeadmin (0.3.2) lib/active_admin/views/pages/base.rb:147:in `build_sidebar'
activeadmin (0.3.2) lib/active_admin/arbre/builder.rb:68:in `build_tag'
activeadmin (0.3.2) lib/active_admin/arbre/builder.rb:96:in `with_current_dom_context'
activeadmin (0.3.2) lib/active_admin/arbre/builder.rb:67:in `build_tag'
activeadmin (0.3.2) lib/active_admin/arbre/builder.rb:77:in `insert_tag'
activeadmin (0.3.2) lib/active_admin/arbre/html/element.rb:13:in `div'
activeadmin (0.3.2) lib/active_admin/views/pages/base.rb:146:in `build_sidebar'
activeadmin (0.3.2) lib/active_admin/views/pages/base.rb:99:in `build_page_content'
activeadmin (0.3.2) lib/active_admin/arbre/builder.rb:68:in `build_tag'
activeadmin (0.3.2) lib/active_admin/arbre/builder.rb:96:in `with_current_dom_context'
activeadmin (0.3.2) lib/active_admin/arbre/builder.rb:67:in `build_tag'
activeadmin (0.3.2) lib/active_admin/arbre/builder.rb:77:in `insert_tag'
activeadmin (0.3.2) lib/active_admin/arbre/html/element.rb:13:in `div'
activeadmin (0.3.2) lib/active_admin/views/pages/base.rb:97:in `build_page_content'
activeadmin (0.3.2) lib/active_admin/views/pages/base.rb:41:in `build_page'
activeadmin (0.3.2) lib/active_admin/arbre/builder.rb:68:in `build_tag'
activeadmin (0.3.2) lib/active_admin/arbre/builder.rb:96:in `with_current_dom_context'
activeadmin (0.3.2) lib/active_admin/arbre/builder.rb:67:in `build_tag'
activeadmin (0.3.2) lib/active_admin/arbre/builder.rb:77:in `insert_tag'
activeadmin (0.3.2) lib/active_admin/arbre/html/element.rb:13:in `div'
activeadmin (0.3.2) lib/active_admin/views/pages/base.rb:38:in `build_page'
activeadmin (0.3.2) lib/active_admin/arbre/builder.rb:96:in `within'
activeadmin (0.3.2) lib/active_admin/views/pages/base.rb:37:in `build_page'
activeadmin (0.3.2) lib/active_admin/views/pages/base.rb:10:in `build'
activeadmin (0.3.2) lib/active_admin/arbre/builder.rb:63:in `build_tag'
activeadmin (0.3.2) lib/active_admin/arbre/builder.rb:77:in `insert_tag'
activeadmin (0.3.2) lib/active_admin/arbre/builder.rb:41:in `send'
activeadmin (0.3.2) lib/active_admin/arbre/builder.rb:41:in `method_missing'
activeadmin (0.3.2) lib/active_admin/view_helpers/renderer_helper.rb:21:in `render'
activeadmin (0.3.2) app/views/active_admin/resource/index.html.arb:1:in `___sers_releu__rvm_gems_ree_______________mtv_blog_gems_activeadmin_______app_views_active_admin_resource_index_html_arb___2081107852_2259082560'
actionpack (3.1.1) lib/action_view/template.rb:144:in `send'
actionpack (3.1.1) lib/action_view/template.rb:144:in `render'
activesupport (3.1.1) lib/active_support/notifications.rb:55:in `instrument'
actionpack (3.1.1) lib/action_view/template.rb:142:in `render'
actionpack (3.1.1) lib/action_view/renderer/template_renderer.rb:40:in `render_template'
actionpack (3.1.1) lib/action_view/renderer/abstract_renderer.rb:33:in `instrument'
activesupport (3.1.1) lib/active_support/notifications.rb:53:in `instrument'
activesupport (3.1.1) lib/active_support/notifications/instrumenter.rb:21:in `instrument'
activesupport (3.1.1) lib/active_support/notifications.rb:53:in `instrument'
actionpack (3.1.1) lib/action_view/renderer/abstract_renderer.rb:33:in `instrument'
actionpack (3.1.1) lib/action_view/renderer/template_renderer.rb:39:in `render_template'
actionpack (3.1.1) lib/action_view/renderer/template_renderer.rb:47:in `render_with_layout'
actionpack (3.1.1) lib/action_view/renderer/template_renderer.rb:38:in `render_template'
actionpack (3.1.1) lib/action_view/renderer/template_renderer.rb:12:in `render'
actionpack (3.1.1) lib/action_view/renderer/abstract_renderer.rb:22:in `wrap_formats'
actionpack (3.1.1) lib/action_view/renderer/template_renderer.rb:9:in `render'
actionpack (3.1.1) lib/action_view/renderer/renderer.rb:36:in `render_template'
actionpack (3.1.1) lib/action_view/renderer/renderer.rb:17:in `render'
actionpack (3.1.1) lib/abstract_controller/rendering.rb:120:in `_render_template'
actionpack (3.1.1) lib/action_controller/metal/streaming.rb:250:in `_render_template'
actionpack (3.1.1) lib/abstract_controller/rendering.rb:114:in `render_to_body'
actionpack (3.1.1) lib/action_controller/metal/renderers.rb:30:in `render_to_body'
actionpack (3.1.1) lib/action_controller/metal/compatibility.rb:43:in `render_to_body'
actionpack (3.1.1) lib/abstract_controller/rendering.rb:99:in `render'
actionpack (3.1.1) lib/action_controller/metal/rendering.rb:16:in `render'
actionpack (3.1.1) lib/action_controller/metal/instrumentation.rb:40:in `render'
activesupport (3.1.1) lib/active_support/core_ext/benchmark.rb:5:in `ms'
/Users/releu/.rvm/rubies/ree-1.8.7-2011.03/lib/ruby/1.8/benchmark.rb:308:in `realtime'
activesupport (3.1.1) lib/active_support/core_ext/benchmark.rb:5:in `ms'
actionpack (3.1.1) lib/action_controller/metal/instrumentation.rb:40:in `render'
actionpack (3.1.1) lib/action_controller/metal/instrumentation.rb:78:in `cleanup_view_runtime'
activerecord (3.1.1) lib/active_record/railties/controller_runtime.rb:24:in `cleanup_view_runtime'
actionpack (3.1.1) lib/action_controller/metal/instrumentation.rb:39:in `render'
actionpack (3.1.1) lib/action_controller/metal/implicit_render.rb:10:in `default_render'
actionpack (3.1.1) lib/action_controller/metal/implicit_render.rb:5:in `send_action'
actionpack (3.1.1) lib/abstract_controller/base.rb:167:in `process_action'
actionpack (3.1.1) lib/action_controller/metal/rendering.rb:10:in `process_action'
actionpack (3.1.1) lib/abstract_controller/callbacks.rb:18:in `process_action'
activesupport (3.1.1) lib/active_support/callbacks.rb:461:in `_run__101774640__process_action__199225275__callbacks'
activesupport (3.1.1) lib/active_support/callbacks.rb:386:in `send'
activesupport (3.1.1) lib/active_support/callbacks.rb:386:in `_run_process_action_callbacks'
activesupport (3.1.1) lib/active_support/callbacks.rb:81:in `send'
activesupport (3.1.1) lib/active_support/callbacks.rb:81:in `run_callbacks'
actionpack (3.1.1) lib/abstract_controller/callbacks.rb:17:in `process_action'
actionpack (3.1.1) lib/action_controller/metal/rescue.rb:17:in `process_action'
actionpack (3.1.1) lib/action_controller/metal/instrumentation.rb:30:in `process_action'
activesupport (3.1.1) lib/active_support/notifications.rb:53:in `instrument'
activesupport (3.1.1) lib/active_support/notifications/instrumenter.rb:21:in `instrument'
activesupport (3.1.1) lib/active_support/notifications.rb:53:in `instrument'
actionpack (3.1.1) lib/action_controller/metal/instrumentation.rb:29:in `process_action'
actionpack (3.1.1) lib/action_controller/metal/params_wrapper.rb:201:in `process_action'
activerecord (3.1.1) lib/active_record/railties/controller_runtime.rb:18:in `process_action'
actionpack (3.1.1) lib/abstract_controller/base.rb:121:in `process'
actionpack (3.1.1) lib/abstract_controller/rendering.rb:45:in `process'
actionpack (3.1.1) lib/action_controller/metal.rb:193:in `dispatch'
actionpack (3.1.1) lib/action_controller/metal/rack_delegation.rb:14:in `dispatch'
actionpack (3.1.1) lib/action_controller/metal.rb:236:in `action'
actionpack (3.1.1) lib/action_dispatch/routing/route_set.rb:65:in `call'
actionpack (3.1.1) lib/action_dispatch/routing/route_set.rb:65:in `dispatch'
actionpack (3.1.1) lib/action_dispatch/routing/route_set.rb:29:in `call'
rack-mount (0.8.3) lib/rack/mount/route_set.rb:152:in `call'
rack-mount (0.8.3) lib/rack/mount/code_generation.rb:96:in `recognize'
rack-mount (0.8.3) lib/rack/mount/code_generation.rb:82:in `optimized_each'
rack-mount (0.8.3) lib/rack/mount/code_generation.rb:95:in `recognize'
rack-mount (0.8.3) lib/rack/mount/route_set.rb:141:in `call'
actionpack (3.1.1) lib/action_dispatch/routing/route_set.rb:532:in `call'
sass (3.1.10) lib/sass/./sass/plugin/rack.rb:54:in `call'
warden (1.0.6) lib/warden/manager.rb:35:in `call'
warden (1.0.6) lib/warden/manager.rb:34:in `catch'
warden (1.0.6) lib/warden/manager.rb:34:in `call'
actionpack (3.1.1) lib/action_dispatch/middleware/best_standards_support.rb:17:in `call'
rack (1.3.5) lib/rack/etag.rb:23:in `call'
rack (1.3.5) lib/rack/conditionalget.rb:25:in `call'
actionpack (3.1.1) lib/action_dispatch/middleware/head.rb:14:in `call'
actionpack (3.1.1) lib/action_dispatch/middleware/params_parser.rb:21:in `call'
actionpack (3.1.1) lib/action_dispatch/middleware/flash.rb:243:in `call'
rack (1.3.5) lib/rack/session/abstract/id.rb:195:in `context'
rack (1.3.5) lib/rack/session/abstract/id.rb:190:in `call'
actionpack (3.1.1) lib/action_dispatch/middleware/cookies.rb:331:in `call'
activerecord (3.1.1) lib/active_record/query_cache.rb:62:in `call'
activerecord (3.1.1) lib/active_record/connection_adapters/abstract/connection_pool.rb:477:in `call'
actionpack (3.1.1) lib/action_dispatch/middleware/callbacks.rb:29:in `call'
activesupport (3.1.1) lib/active_support/callbacks.rb:392:in `_run_call_callbacks'
activesupport (3.1.1) lib/active_support/callbacks.rb:81:in `send'
activesupport (3.1.1) lib/active_support/callbacks.rb:81:in `run_callbacks'
actionpack (3.1.1) lib/action_dispatch/middleware/callbacks.rb:28:in `call'
actionpack (3.1.1) lib/action_dispatch/middleware/reloader.rb:68:in `call'
rack (1.3.5) lib/rack/sendfile.rb:101:in `call'
actionpack (3.1.1) lib/action_dispatch/middleware/remote_ip.rb:48:in `call'
actionpack (3.1.1) lib/action_dispatch/middleware/show_exceptions.rb:47:in `call'
railties (3.1.1) lib/rails/rack/logger.rb:13:in `call'
rack (1.3.5) lib/rack/methodoverride.rb:24:in `call'
rack (1.3.5) lib/rack/runtime.rb:17:in `call'
activesupport (3.1.1) lib/active_support/cache/strategy/local_cache.rb:72:in `call'
rack (1.3.5) lib/rack/lock.rb:15:in `call'
actionpack (3.1.1) lib/action_dispatch/middleware/static.rb:53:in `call'
railties (3.1.1) lib/rails/engine.rb:456:in `call'
railties (3.1.1) lib/rails/rack/content_length.rb:16:in `call'
railties (3.1.1) lib/rails/rack/log_tailer.rb:14:in `call'
rack (1.3.5) lib/rack/handler/webrick.rb:59:in `service'
/Users/releu/.rvm/rubies/ree-1.8.7-2011.03/lib/ruby/1.8/webrick/httpserver.rb:104:in `service'
/Users/releu/.rvm/rubies/ree-1.8.7-2011.03/lib/ruby/1.8/webrick/httpserver.rb:65:in `run'
/Users/releu/.rvm/rubies/ree-1.8.7-2011.03/lib/ruby/1.8/webrick/server.rb:173:in `start_thread'
/Users/releu/.rvm/rubies/ree-1.8.7-2011.03/lib/ruby/1.8/webrick/server.rb:162:in `start'
/Users/releu/.rvm/rubies/ree-1.8.7-2011.03/lib/ruby/1.8/webrick/server.rb:162:in `start_thread'
/Users/releu/.rvm/rubies/ree-1.8.7-2011.03/lib/ruby/1.8/webrick/server.rb:95:in `start'
/Users/releu/.rvm/rubies/ree-1.8.7-2011.03/lib/ruby/1.8/webrick/server.rb:92:in `each'
/Users/releu/.rvm/rubies/ree-1.8.7-2011.03/lib/ruby/1.8/webrick/server.rb:92:in `start'
/Users/releu/.rvm/rubies/ree-1.8.7-2011.03/lib/ruby/1.8/webrick/server.rb:23:in `start'
/Users/releu/.rvm/rubies/ree-1.8.7-2011.03/lib/ruby/1.8/webrick/server.rb:82:in `start'
rack (1.3.5) lib/rack/handler/webrick.rb:13:in `run'
rack (1.3.5) lib/rack/server.rb:265:in `start'
railties (3.1.1) lib/rails/commands/server.rb:70:in `start'
railties (3.1.1) lib/rails/commands.rb:54
railties (3.1.1) lib/rails/commands.rb:49:in `tap'
railties (3.1.1) lib/rails/commands.rb:49
script/rails:6:in `require'
script/rails:6

I'm guessing this is a bug report?

it's related to metasearch, i peeped into the code(activeadmin gem) but did not find any solution to that.

Definitely a bug - seems there is no way to override the default collection. There should really be a way that does not involved opening the controller.

Something like:

base_collection { Foo.where(:not_broken => true) }

+1 to @allix
Just now it works only for relationship. But if I need ovveride default collection - then nothing :(

+1, This bug really drives me crazy

controller do
def index
@posts = Post.where(:enabled => true).page(params[:page])
respond_to do |format|
format.html{ use your html template now (eg. render "active_admin/discharged_patients/index"}
format.csv{ use your csv template now"}
format.xml{ use your xml template now}
end
end
end

this is how u can solved this problem, it means, if u don't specify "page(params[:page])" , it will yield error
undefined method `num_pages' for #ActiveRecord::Relation:0x10d65e560.

now if u don't override the html template it will yield error
undefined method `base' for nil:NilClass
so create ur own index template also,
eg. in ur views/active_admin/controller_name/index.html.erb

if u are overriding the index action u have to use ur own template, but after this u will loose active_admin layout.

Feel this is a very serious bug, hoping to solve the

This bug is due to active_admin's FormBuilder expecting an instance variable called "search". It is normally added by ActiveAdmin's Resource controller. My workaround follows:

ActiveAdmin.register District do
  collection_action :index, :method => :get do
      scope = District.scoped

      @collection = scope.page() if params[:q].blank?
      @search = scope.metasearch(clean_search_params(params[:q]))

      respond_to do |format|
        format.html {
          render "my/own/template" # or "active_admin/resource/index"
        }
      end
    end
end

very good,thank eugene

Thank you eugene

eugene, where would a custom filter go in your example? I have Users who have a HABTM relationship with Organizations. My Ballot resource belongs to an Organization so I want only users to see ballots in their ogranization...

This generates the right SQL in the logs, but unsure where to place in the collection_action

Ballot.find(:all, :conditions => ["organization_id IN (?)", current_user_organizations])

app/controllers/application_controller.rb

  def current_user_organizations
    current_user.organizations.find(:all)
  end 

The collection_action seems the only way to make this work

    def index
      index! do |format|
        collection = Ballot.find(:all, :conditions => ["organization_id IN (?)", current_user_organizations])

        format.html {
          render "active_admin/resource/index"
        }   
      end 
    end 

Using only the above index override , the correct SQL is called but is then is overridden by the active_admin collection call

  User Load (0.1ms)  SELECT `users`.* FROM `users` WHERE `users`.`id` = 3 LIMIT 1
  Organization Load (0.1ms)  SELECT `organizations`.* FROM `organizations` INNER JOIN `organizations_users` ON `organizations`.`id` = `organizations_users`.`organization_id` WHERE `organizations_users`.`user_id` = 3
  Ballot Load (0.2ms)  SELECT `ballots`.* FROM `ballots` WHERE (organization_id IN (1))
   (0.2ms)  SELECT COUNT(count_column) FROM (SELECT 1 AS count_column FROM `ballots` LIMIT 30 OFFSET 0) subquery_for_count 
   (0.6ms)  SELECT COUNT(*) FROM `ballots` 
  CACHE (0.0ms)  SELECT COUNT(count_column) FROM (SELECT 1 AS count_column FROM `ballots` LIMIT 30 OFFSET 0) subquery_for_count 
  CACHE (0.0ms)  SELECT COUNT(count_column) FROM (SELECT 1 AS count_column FROM `ballots` LIMIT 30 OFFSET 0) subquery_for_count 
  Ballot Load (0.8ms)  SELECT `ballots`.* FROM `ballots` ORDER BY `ballots`.id desc LIMIT 30 OFFSET 0

Thanks

Resolved my previous issue with the following...

  collection_action :index, :method => :get do
    scope = Ballot.where(:organization_id => current_user_organizations).scoped

    @collection = scope.page() if params[:q].blank?
    @search = scope.metasearch(clean_search_params(params[:q]))

    respond_to do |format|
      format.html {
        render "active_admin/resource/index"
      }   
    end 
  end 

It's working great and prevents the filters from showing the items during a search, thanks eugene

To override the default collection and eager load association, you can either :

  • use scope_to


scope_to :association_method => :scoped do
User.includes(:role)
end

  • override action scoped_collection in the controller, allow to


controller do
def scoped_collection
User.includes(:role)
end
end

Thank you eugene.
It works for me.

For my "Group" model, the collection approach works well but for the "Item" model, it does not work and return the following error:

undefined method `page' for #<Array:0xc240bc4>

I use this code in admin/items.rb: => does not work

collection_action :index, :method => :get do
  # Only get the items belonging to a group owned by the current user
  scope = Group.where("owner_id = ?", current_user.id).map{|group| group.items}

  @collection = scope.page() if params[:q].blank?
  @search = scope.metasearch(clean_search_params(params[:q]))

   respond_to do |format|
   format.html {
     render "active_admin/resource/index"
   }
 end
end

In admin/groups.rb, the following works fine though:

collection_action :index, :method => :get do
  # Only get the groups owned by the current user
  scope = Group.where("owner_id = ?", current_user.id).scoped

  @collection = scope.page() if params[:q].blank?
  @search = scope.metasearch(clean_search_params(params[:q]))

  respond_to do |format|
    format.html {
      render "active_admin/resource/index"
    }
  end
end

Hello, everyone!

Eugene's trick works. But i dont understand why i can not use

  scope = Category.scoped
  @categories = scope.page() if params[:q].blank?
  @search = scope.metasearch(clean_search_params(params[:q]))

instead of

@categories = Category.all

?

Why need I use scope?

Thanks

HI @izumeroot, this ticket is rather old; why not take the standard approach?

controller do
  def scoped_collection
    resource_class.foo.bar.baz
  end
end

Hi, Daxter!
But where is respond_to block? I need json and html responds in action...

And also how can I write analog for

@category = Category.find(params[:id])

?

What exactly are you trying to accomplish? If all you need is to customize which records show up, use the scoped_collection option. There's no need to redefine controller actions; the CSV, JSON, etc. download links use the same source.

As for an analog for:

@category = Category.find(params[:id])

Two methods are automatically built for you by Inherited Resources

resource # does the same thing as Category.find
category # does the same thing as above, but is named after the class in question

I need migrate one of my rails controllers to active_admin.
Now I have something like this


ActiveAdmin.register Category do

  config.clear_sidebar_sections!

  controller do
    layout 'active_admin'

    def index
      #@categories = Category.all

      scope = Category.scoped

      @categories = scope.page() if params[:q].blank?
      @search = scope.metasearch(clean_search_params(params[:q]))

      respond_to do |format|
        format.html # index.html.erb
        format.json { render json: @categories }
      end
    end

    # POST /categories
    # POST /categories.json
    def create
    @category = Category.new(params[:category])

      respond_to do |format|
        if @category.save
          expire_fragment('category_nav')
          expire_fragment('category_tree_data')
          format.html { redirect_to @category, notice: 'Category was successfully created.' }
          format.json { render json: @category, status: :created, location: @category }
          format.js { render :nothing => true }
        else
          format.html { render action: "new" }
          format.json { render json: @category.errors, status: :unprocessable_entity }
        end
      end
    end

  # ......................................

  end
end

If I use @categories = Category.all instead of

@categories = scope.page() if params[:q].blank?
@search = scope.metasearch(clean_search_params(params[:q]))

I get error "undefined method `base' for nil:NilClass"

That index action doesn't do anything custom, so you can just remove it and let Active Admin handle it.

If i remove custom index, the ActiveAdmin ignores my custom view-file (with tree and chechbox groups):

app/views/admin_ui/categories/index.html.slim

and displays default grid.

If you move that file to app/views/admin/categories/index.html.slim, then Active Admin will automatically grab it.

If you want to preserve the AA layout, add this as well:

controller do
  def index
    index! do |format|
      format.html{ render layout: 'active_admin' }
    end
  end
end

There might be a cleaner way to preserve the layout, but I'm not sure what it would be.

If you just set layout 'active_admin' but don't create custom views for every page relating to the resource, you run into this:
screen shot 2013-10-01 at 2 29 38 pm

Thank you very much!!!
Trick with "format.html{ render layout: 'active_admin' }" works fine!
Just I need not move view, because in config I have config.default_namespace = :admin_ui

Can I ask one more question about controller mirgation?
I need execute some code before or after default action of ActiveAdmin. How can I do it?
I need something like this:

def update 
    run_before_code
    run_active_admin_update_action
    run_after_code
end

I don't know about running code after, but to run code before just put it before, like this:

controller do
  def update
    # do stuff here
    update!
  end
end

The docs for Inherited Resources are really descriptive: https://github.com/josevalim/inherited_resources

Thanks for help!

Good morning!

Sorry. One more querstion, if you can.

How can I add css and js files for my Category page (not for whole active_admin).
I tried use

- content_for :head do
  = javascript_include_tag "active_admin/categories"
  = stylesheet_link_tag "active_admin/categories"

But look like in main active_admin template we have not

yield :head

Need I redefine main active_admin template? :(

I found solution:

ActiveAdmin.register Category do
    ActiveAdmin.application.javascripts << 'active_admin/categories'
    ActiveAdmin.application.stylesheets.merge!({'active_admin/categories' => {:media => :screen}})

Hello!

Uhh.. no..
If I did so

ActiveAdmin.register Category do
    ActiveAdmin.application.javascripts << 'active_admin/categories'
    ActiveAdmin.application.stylesheets.merge!({'active_admin/categories' => {:media => :screen}}

then it loads for each active_admin controller. But I need it for category controller only.

Do anybody know correct way?

There isn't any easy way to conditionally include different assets. What you should instead do is include those assets normally, but scope them to the specific page.

There isn't an easy way to do it because you shouldn't do it. It's a Rails convention to compile all assets into a single file.

So, it is single file (lib/active_admin_views_pages_base.rb):

..............  
def build_active_admin_head
    within @head do
    insert_tag Arbre::HTML::Title, [title, render_or_call_method_or_proc_on(self, active_admin_application.site_title)].join(" | ")
    active_admin_application.stylesheets.each do |style, options|
        text_node stylesheet_link_tag(style, options).html_safe
    end

    text_node stylesheet_link_tag("active_admin/#{controller.controller_name}", {:media => :screen}).html_safe

    active_admin_application.javascripts.each do |path|
        text_node(javascript_include_tag(path))
    end

    text_node(javascript_include_tag("active_admin/#{controller.controller_name}"))

    if active_admin_application.favicon
        text_node(favicon_link_tag(active_admin_application.favicon))
    end

    text_node csrf_meta_tag
    end
end
    ............................

I want to show only one record in index action of companies in activeadmin. Is there a way to do it? I tried scoped collection, but I think it is expecting collection so I am getting error as undefined method `reorder' for #Company:0xb8a9804. Please help me.

@railsfactory-madhusudhan scoped_collection needs to return a query object not a Company instance! You can do:

controller do
  def scoped_collection
    super.where(id: 1)
  end
end

or

controller do
  def scoped_collection
    super.limit(1)
  end
end

now you need to use scope_collection method, not the scoped & metasearch way.

  controller do
    def scoped_collection
      params[:supplier_id] ? Car.where(supplier_id: params["supplier_id"]) : Car.all
    end
  end

thanks @timoschilling and @seaify both solution works!!

Very thanks @timoschilling and @seaify

Hi there!
Maybe it does not have much to see or is not directly related to the main topic. But I what to download CSV files but not the entire records from a table instead export a custom query or a specific scope. I don't want to only customize the columns but also the records that are exported in the CSV file.
I read that it is related to the info you are viewing in the index page but I want the specific records to be exported and it does not matter if the whole records are shown in the index page, I just want to download a specific query or scope.

Any help or suggestion?
I hope I could be clear.

It Works for me

scope_to :index => :scoped do
current_user_profile.organizations.first
end

HI @izumeroot, this ticket is rather old; why not take the standard approach?

controller do
  def scoped_collection
    resource_class.foo.bar.baz
  end
end

this worked with me

 controller do
    def scoped_collection
      resource_class.current_venodor_products(current_admin)
    end
  end

current_venodor_products is a scope show only records owned by the current vendor

Was this page helpful?
0 / 5 - 0 ratings

Related issues

gauthamns picture gauthamns  路  34Comments

joker-777 picture joker-777  路  39Comments

robotmay picture robotmay  路  61Comments

simontol picture simontol  路  28Comments

seanlinsley picture seanlinsley  路  75Comments