ActiveAdmin 索引视图中的可排序自定义列:连接、分组和计数地狱
Sortable custom column in ActiveAdmin index view : joins, group and count hell
我们正在为我们的管理视图使用 ActiveAdmin,这是当前的索引代码。 Book 模型从单个 "books" postgres table 检索数据:
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
...
我想在我们的索引视图中添加一个 "stories" 列。 "story" 是来自用户的动作,与一本书相关联。故事存储在 "book_stories" table.
中
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;
而且我真的不知道如何在我们的管理视图中实现 sortable "Stories" 列。通过 sortable,我的意思是,能够像按故事计数一样对书进行排序。我设法用这段代码显示每本书的故事数,但该列不是 sortable :
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
...
有什么想法吗?
查看 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
好的,它正在运行。非常感谢你 !这是我的代码:
图书型号:
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
仍在调查中...
我们正在为我们的管理视图使用 ActiveAdmin,这是当前的索引代码。 Book 模型从单个 "books" postgres table 检索数据:
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
...
我想在我们的索引视图中添加一个 "stories" 列。 "story" 是来自用户的动作,与一本书相关联。故事存储在 "book_stories" table.
中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;
而且我真的不知道如何在我们的管理视图中实现 sortable "Stories" 列。通过 sortable,我的意思是,能够像按故事计数一样对书进行排序。我设法用这段代码显示每本书的故事数,但该列不是 sortable :
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
...
有什么想法吗?
查看 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
好的,它正在运行。非常感谢你 !这是我的代码:
图书型号:
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
仍在调查中...