ActiveAdmin索引视图中的可排序自定义列:连接,分组和计数地狱

时间:2015-08-27 15:14:04

标签: ruby-on-rails ruby-on-rails-3 activerecord rails-activerecord activeadmin

我们在管理视图中使用ActiveAdmin,这是当前的索引代码。 Book模型从单个"书籍中检索数据。 postgres表:

class Book < ActiveRecord::Base

  has_many :stories, class_name: "BookStory"

...

 ActiveAdmin.register Book do

  index do
    column :id
    column :title
    column :subtitle
    column :isbn_13
    default_actions
  end
...

我想添加一个&#34;故事&#34;我们的索引视图中的列。 A&#34;故事&#34;是来自用户的与书籍相关联的动作。故事存储在&#34; book_stories&#34;表

class BookStory < ActiveRecord::Base

  belongs_to :user,
  belongs_to :book,

从SQL的角度来看,这就是我想将查询实现到ActiveAdmin的方式。这个查询给了我想要的结果到pgAdmin3:

SELECT books.id,books.title,books.subtitle,books.isbn_13,COUNT(book_stories.book_id) AS count
FROM books 
INNER JOIN book_stories ON books.id = book_stories.book_id
GROUP BY books.id
ORDER BY count DESC
LIMIT 30;

我真的不知道如何实施可排序&#34; Stories&#34;列进入我们的管理视图。通过排序,我的意思是,能够像他们的故事一样对书进行排序。我设法使用此代码显示每本书的故事数,但该列不可排序:

 ActiveAdmin.register Book do

  index do
    column :id
    column :title
    column :subtitle
    column :isbn_13
    column :stories do |book|
    BookStory.joins(:book).group.where("books.id = #{book.id}").count
    default_actions
  end
...

有什么想法吗?

2 个答案:

答案 0 :(得分:1)

查看belongs_to counter_cache选项。 http://guides.rubyonrails.org/association_basics.html#counter-cache

class BookStory < ActiveRecord::Base
  belongs_to :book, counter_cache: true
end

ActiveAdmin.register Book do
  index do
    column :id
    column :title
    column :subtitle
    column :isbn_13
    column :book_stories_count # will be sortable by default
    default_actions
  end
end

答案 1 :(得分:0)

好的,它正在发挥作用。非常感谢你 !这是我的代码:

书籍型号:

class Book < ActiveRecord::Base

  has_many :stories, class_name: "BookStory"

书籍故事模型:

class BookStory < ActiveRecord::Base

  belongs_to :user, :counter_cache => true
  belongs_to :book, :counter_cache => true

迁移文件:

class AddBookStoriesCountColumn < ActiveRecord::Migration
  def self.up
    add_column :books, :book_stories_count, :integer, :null => false, :default => 0
    Book.reset_column_information
    Book.find_each do |b|
      Book.reset_counters b.id, :stories
    end
  end

  def self.down
    remove_column :books, :book_stories_count
  end
end

索引视图:

ActiveAdmin.register Book do

  index do
    column :id
    column :title
    column :subtitle
    column :isbn_13
    column :book_stories_count
    default_actions
  end

我还创建了一个rake任务,以便在需要时手动更新计数器:

  task :update_counters => [:environment] do
    Book.reset_column_information
    Book.find_each do |b|
      Book.reset_counters b.id, :stories
    end

现在,我想为用户实现一个故事计数器。而且我相信我只需要在这里使用相同的代码,只需将“Book”改为“User”,但我还有其他问题。

用户模型:

class User < ActiveRecord::Base

  has_many :book_actions
  has_many :book_stories
  has_many :books, through: :book_stories

但是当我尝试更新/重置计数器

时,我输入了一个错误
NoMethodError: undefined method `options' for nil:NilClass

仍在调查......