Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ActiveAdmin how to sort column with associations

I'm developing an ActiveAdmin app, and I want to sort a column of businesses by their "type". Unfortunately my code is not working. What code should I use to accomplish this? Here is my code...

app/models/business.rb


class Business < ActiveRecord::Base   
     belongs_to :type

     attr_accessible :description, :email, :facebook, :foursquare, :google, :manager,
    :mobile, :name, :phone, :type_id, :url, :yelp 
end

app/models/type.rb


class Type < ActiveRecord::Base
  attr_accessible  :category
  has_many :businesses

  def to_s
    category
  end
end

app/admin/businesses.rb


ActiveAdmin.register Business, { :sort_order => :name_asc } do
  scope :joined, :default => true do |businesses|
    businesses.includes [:type]
  end
  index do
    column :name
    column :type, :sortable => 'businesses.type'
    column :manager
    column :email
    default_actions
  end
end

Thanks!

like image 343
Slicekick Avatar asked Jun 21 '12 23:06

Slicekick


4 Answers

according to this discussion: https://github.com/gregbell/active_admin/pull/623, if you don't want to use scopes, you can use the scoped collection method instead:

ActiveAdmin.register Business, { :sort_order => :name_asc } do
  scope :all, :default => true

  index do
    column :name
    column :type, :sortable => 'types.category'
    column :manager
    column :email
    default_actions
  end

  controller do
    def scoped_collection
      end_of_association_chain.includes(:type)
    end
  end
end
like image 104
Evgeniya Manolova Avatar answered Nov 18 '22 23:11

Evgeniya Manolova


FIXED

column :type, :sortable => 'types.category'

like image 33
Slicekick Avatar answered Nov 18 '22 22:11

Slicekick


Yes, the scoped_collection Evgenia provided works great. Also for more than one columns:

ActiveAdmin.register Foo do
  index do
    column :field_name_a, :sortable => 'association_a.field_name'
    column :field_name_b, :sortable => 'association_b.field_name'
  end
end

controller do
  def scoped_collection
    end_of_association_chain.includes([:association_a, :association_b])
  end
end
like image 4
Rimian Avatar answered Nov 18 '22 21:11

Rimian


This can be done.

Here I have a model called Star. A star belongs to a Person. I'm going to put the Person.name in the Star admin index, make it sortable, make it work with scopes, and add filters.

First you have to add the join model to each of your scopes. In this case I had 3 scopes: all, category_subscriptions and person_subscriptions. I'm declaring the scopes and adding the join model to them:

ActiveAdmin.register Star do
  [ :all, :category_subscriptions, :person_subscriptions ].each do |sym|
    scope(sym, :default => (sym == :all) ) do |stars|
      stars.includes [:person]
    end
  end
end

Now to add the person name from the join model into my star index I do this:

index do
  id_column
  column("Name", nil, :sortable => :"people.name") {|star| star.person.name}
  column("Email", nil, :sortable => :"people.email") {|star| star.person.email}
  default_actions
end

Let's dissect that:

column("Name", nil, :sortable => :"people.name") {|star| star.person.name}
  • The first parameter is the column title.
  • The second is not needed since we're overriding sort and the value.
  • :sortable tells Active Admin how to sort the thing. This is the table name, since it's going into SQL.
  • The block tells Active Admin what to use as a row value.

Now to add some filters. This is much easier:

filter :person_name, :as => :string
filter :person_email, :as => :string

And you're done.

like image 4
superluminary Avatar answered Nov 18 '22 23:11

superluminary