class Attachment < ActiveRecord::Base
belongs_to :user, foreign_key: :creator_id
belongs_to :deal_task, foreign_key: :relation_id
end
class DealTask < ActiveRecord::Base
has_many :attachments, foreign_key: :relation_id
end
我有名为DealTask的父表和名为Attachment的子表
我想要一个DealTask记录列表以及相关的附件总数
答案 0 :(得分:1)
DealTask.all.map do |deal_task|
deal_task.
attributes.
with_indifferent_access.
slice(:id, :name).
merge!(total_attachment: deal_task.attachments.count)
end
或者,如果您不关心无关紧要的访问权限,并且您不介意拥有所有DealTask
属性,那么您可以在一行中写下这一点:
DealTask.all.map{|deal_task| deal_task.attributes.merge!(total_attachments: deal_task.attachments.count)}
打破它......
DealTask.all.map do |deal_task|
...
end
将返回array
。 array
将包含do
块的结果。
deal_task.
attributes.
with_indifferent_access
为您提供可以使用deal_task
或strings
访问的哈希中每个symbols
的属性(因此,&#34; indifferent_access&#34;)。
deal_task.
attributes.
with_indifferent_access.
slice(:id, :name)
仅保留:id
哈希的:name
和deal_task
。
merge!(total_attachments: deal_task.attachments.count)
使用键total_attachments
将附件计数添加到您的哈希。
结果应该类似于:
[
{id: 1, name: 'name1', total_attachments: 12},
{id: 2, name: 'name2', total_attachments: 3}
]
答案 1 :(得分:0)
试试这个
DealTask.all.map { |deal_task| deal_task.attachments.ids }.count
答案 2 :(得分:0)
isLocalNotification
DealTask.first.attachments.count #This will give count of attachemenets
或者
#To show all records and all the count
DealTask.find_each do |dt|
print dt.inspect
print "\n"
print dt.attachments.count
end
格式更好
DealTask.joins(:attachments).select("deal_tasks.*, count(attachements.id) as count").group("deal_tasks.id")
当您在单个查询中获取所有数据时,这将快得多
答案 3 :(得分:0)
我找到了父母子女关系计数的最佳解决方案
counter_cache: true
因为以上所有查询都需要花费太多时间从数据库加载
所以你们都喜欢使用这个
1→在名为 DealTask
的父表中添加一列rails g migration AddAttachmentsCountToDealTask attachments_count:integer
2→打开迁移添加编辑
class AddAttachmentCountToDealTask < ActiveRecord::Migration[5.0]
def up
add_column :deal_tasks, :attachments_count, :integer, default: 0
DealTask.reset_column_information
DealTask.find_each do |deal_task|
DealTask.reset_counters deal_task.id, :attachments
end
end
def down
remove_column :deal_tasks, attachments_count
end
end
因此,当您回滚迁移时,它不会引发错误或异常
您也可以使用任何循环而不是使用
find_each, DealTask.all.each do...end
但是,是的,重置计数器必须使用类名称
DealTask.reset_counters
3→设置计数器缓存
class Attachment < ActiveRecord::Base
belongs_to :deal_task, foreign_key: :relation_id, counter_cache: true
end
class DealTask < ActiveRecord::Base
has_many :attachments, foreign_key: :relation_id
end
假设您的模型名称 sub_tasks ,而您的counter_cache列必须
sub_tasks_count
如果您需要自己的列名,则必须在counter_cache中指定该列名
假设列名是total_subtasks而不是
belongs_to :deal_task, foreign_key: :relation_id, counter_cache: :total_subtasks
并相应地进行更改以更新counter_cache
现在当您添加任何附件时, attachments_count 列增加1,这将由** counter_cache自动完成
有一个问题 **当你删除任何一个孩子时,counter_cache无法减少**
因此该解决方案进行回调
class Attachment < ActiveRecord::Base
belongs_to :deal_task, foreign_key: :relation_id, counter_cache: true
before_destroy :reset_counter
private
def reset_counter
DealTask.reset_counters(self.relation.id, :attachments)
end
end
因此,当您删除任何附件时,它将通过 relation_id 重置其父项的countet_cache,即parent_id或附件的Foreign_key
了解更多信息 观看Railscast counter cache 23
上的视频