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

Спасибо!


person Slicekick    schedule 21.06.2012    source источник
comment
Кто угодно? Я все еще сталкиваюсь с этим блокпостом...   -  person Slicekick    schedule 25.06.2012


Ответы (5)


согласно этому обсуждению: 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
person Evgeniya Manolova    schedule 31.01.2013
comment
Возможно, вам придется связать .references(:type) после includes(:type), чтобы получить соединение в более поздних версиях ActiveRecord. - person ahmacleod; 28.09.2015
comment
@ahmacleod, где я могу узнать больше о том, что вы упомянули об использовании .references(:type) в более поздних версиях ActiveRecord? Или вы можете уточнить немного больше для меня, пожалуйста? - person alexventuraio; 23.03.2018

ИСПРАВЛЕНО

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

person Slicekick    schedule 24.06.2012
comment
Я не понимаю? Это то же самое, что и выше? - person cjm2671; 27.02.2014

Да, Scoped_Коллекция, предоставленная Евгенией, отлично работает. Также для более чем одного столбца:

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
person Rimian    schedule 15.02.2013

Это можно сделать.

Вот у меня есть модель под названием Star. Звезда принадлежит Человеку. Я собираюсь поместить Person.name в индекс администратора Star, сделать его сортируемым, заставить его работать с областями и добавить фильтры.

Сначала вам нужно добавить модель соединения в каждую из ваших областей. В этом случае у меня было 3 области: все, 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

И вы сделали.

person superluminary    schedule 15.05.2013

Исходя из ваших потребностей, это моя реализация, работающая для сортировки, индекса по умолчанию и фильтрации:

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
person heriberto perez    schedule 08.10.2018