ActiveAdmin如何使用关联对列进行排序

时间:2012-06-21 23:34:11

标签: ruby-on-rails associations activeadmin

我正在开发一个ActiveAdmin应用程序,我想按照“类型”对一列业务进行排序。不幸的是我的代码无效。我应该用什么代码来完成这个?这是我的代码......

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

谢谢!

5 个答案:

答案 0 :(得分:19)

根据此讨论:https://github.com/gregbell/active_admin/pull/623,如果您不想使用范围,则可以改为使用范围集合方法:

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

答案 1 :(得分:8)

<强>固定

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

答案 2 :(得分:4)

是的,提供的scoped_collection Evgenia效果很好。也适用于多个列:

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

答案 3 :(得分:3)

这可以做到。

这里我有一个名为Star的模型。一颗星属于一个人。我将把Person.name放在Star admin索引中,使其可以排序,使其适用于范围,并添加过滤器。

首先,您必须将连接模型添加到每个范围。在这种情况下,我有3个范围:all,category_subscriptions和person_subscriptions。我正在声明范围并将连接模型添加到它们中:

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

现在将连接模型中的人名添加到我的星形索引中,我这样做:

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

让我们剖析一下:

column("Name", nil, :sortable => :"people.name") {|star| star.person.name}
  • 第一个参数是列标题。
  • 第二个是不需要的,因为我们正在重写排序和价值。
  • :sortable告诉Active Admin如何对事物进行排序。这是表名,因为它将进入SQL。
  • 该块告诉Active Admin将什么用作行值。

现在添加一些过滤器。这更容易:

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

你已经完成了。

答案 4 :(得分:0)

根据您的需求,这是我的实现,用于排序,默认索引和过滤:

ActiveAdmin.register Business do
  index do
    column :name
    column :type, :sortable => 'businesses.type'
    column :manager
    column :email
    default_actions
  end

  controller do
    def scoped_collection
      super.includes(:businesses)
    end
  end
end

以防万一您想知道如何在具有更高级别的关联时进行排序,这就是我正在处理的方式,例如:

class TechResult < ActiveRecord::Base
  belongs_to :user
end

class User < ActiveRecord::Base
  belongs_to :organization
end

class Organization < ActiveRecord::Base
  has_many :users
end

,然后在tech_results部分中,您想要呈现一个组织字段,在我的情况下,值为tech_result.user.organization.name,这是将它们整理出来的一种方式:

ActiveAdmin.register TechResult do
  config.batch_actions = false
  permit_params :user_id

  preserve_default_filters!

  index do
    column :id
    column 'user', sortable: 'users.name' do |tr|
      tr.user.name
    end
    column 'organization', nil, sortable: 'organizations.name' do |tr|
      tr.user.organization.name.titleize if tr.user.organization
    end

  end

  controller do
    def scoped_collection
      super.includes(user: [:organization])
    end
  end
end