Ruby on rails 我如何提取“a”;表「;来自Rails中的ActiveRecords数组?

Ruby on rails 我如何提取“a”;表「;来自Rails中的ActiveRecords数组?,ruby-on-rails,arrays,activerecord,Ruby On Rails,Arrays,Activerecord,我有几个类似的型号(ContactEmail、ContactLetter、ContactPostalcard) 比如说,ContactEmail中的每个实例(记录)都意味着向特定联系人发送了特定的电子邮件模板 因此,每一封(如ContactEmail)都属于:contact 因此,在ContactEmail模型中,有一个属性ContactEmail.contact\u id 每个联系人都有一个虚拟属性company\u name 因此,当我写以下内容时,我将在特定的条件(在本例中为时间)内收到所

我有几个类似的型号(ContactEmail、ContactLetter、ContactPostalcard)

比如说,ContactEmail中的每个实例(记录)都意味着向特定联系人发送了特定的电子邮件模板

因此,每一封(如ContactEmail)
都属于:contact

因此,在ContactEmail模型中,有一个属性
ContactEmail.contact\u id

每个联系人都有一个虚拟属性company\u name

因此,当我写以下内容时,我将在特定的条件(在本例中为时间)内收到所有发送的电子邮件:

所以,
@sent_emails.size
会告诉我所有发送的电子邮件的总数

我的挑战:如何通过不同型号的独特公司提取更多粒度?

我想要的输出如下所示:

FROM 8/1/10 TO 8/10/10 (where the dates are dynamic)

                Calls       Letter      Postalcards
Company 1         4           2             4
Company 2        10           4             6
Company 3         2           3             4
因此,Company3有2个呼叫,这意味着有两个ContactCalls记录,其中发送日期介于这两个日期之间,并且关联的联系人属于Company 3

公司1-3没有提前设定。它需要从ContactCalls、ContactLetters和ContactPostalcards池中提取

挑战在于我不知道这些公司是什么。它们是每个不同记录的联系人部分的属性。因此,在某些情况下,我可能有公司2有0个字母

谢谢你的指导!:)

如何在联系人的给定记录上查找公司电子邮件型号:

ContactEmail.contact.company.name

这将返回特定联系人的关联公司电子邮件

在我看来,尝试在一个查询中提取此数据(我想你会这么做)有点过分了。我将使用
:group=>company\u name
选项为每种类型发出一个查询。然后我会使用Ruby代码合并结果,这样我就有了一些数据结构,可以方便地显示(可能是散列,例如,
{'Company 1'=>{'Calls'=>5,'Letter'=>0,'Postalcards'=>3'}…)

如果您真的想拥有所有这些关系的所有联系人,最好使用计数器缓存

-在此页上查找计数器缓存

它所做的是自动对每个联系人的关系上的计数进行非规范化跟踪,因此您不必从联系人分组的所有表中查询信息,这可能会导致性能问题

您需要做的是将“电子邮件计数”、“信件计数”和“明信片计数”列添加到您的“联系人”表中,最初使用正确的计数进行更新,并声明您有许多关系:

class Contact < ActiveRecord::Base
  has_many :emails, :class_name => 'ContactEmail', :counter_cache => 'emails_count'
  # so on for other columns
end
class联系人“ContactEmail”,:counter\u cache=>“emails\u count”
#其他专栏也是如此
结束

使用这些设置,您只需查询您的联系人,并检查其计数器缓存即可呈现您的表。每次为该联系人创建或销毁项目时,rails都会自动更新其编号。

哦,所以我一开始误解了您的问题。我想我终于明白您的意思了

因此,确实,要做您想要做的事情(即从所有这些表中提取所有数据),唯一好的方法是在查询联系人时发出include:

@contacts = Contact.all :include => [:contact_emails, :contact_letters, :contact_postal_cards]
这将生成4个查询,选择这4个表上的所有数据,并相应地填充联系人,因此您可以以任何方式填充表来浏览联系人对象的关系

最后,您提到您的表将按公司分组,而不是按联系人分组,因此我假设多个联系人可能具有相同的“公司名称”。如果是这样,您可以按“公司名称”对集合进行分组,如下所示

@companies = @contacts.group_by &:company_name
这将创建如下所示的哈希:

{'Company 1' => [contact_1, contact_3], 'Company 2' => [contact_4]}
<% @companies.each do |company_name, contacts| %>
    Company: <%= company_name %>
    <% contacts.each do |contact| %>
       Contact: <%= contact.name %>
          Emails : <%= contact.contact_emails.map(&:email).split(',') %>
          etc..
    <% end %>
<% end %>
有了这些功能,您可以使用以下内容生成表:

{'Company 1' => [contact_1, contact_3], 'Company 2' => [contact_4]}
<% @companies.each do |company_name, contacts| %>
    Company: <%= company_name %>
    <% contacts.each do |contact| %>
       Contact: <%= contact.name %>
          Emails : <%= contact.contact_emails.map(&:email).split(',') %>
          etc..
    <% end %>
<% end %>

公司:
联系人:
电子邮件:
等

这应该可以很好地做到:

    list = Contact.find :all,
      :select => "companies.name company_name, COUNT(contact_emails.id) email_count, COUNT(contact_letters.id) letter_count, COUNT(contact_postalcards.id) postalcard_count",
      :joins => [
        "LEFT JOIN companies ON company.id = contact.company_id",
        "LEFT JOIN contact_emails ON contact_emails.contact_id = contacts.id",
        "LEFT JOIN contact_letters ON contact_letters.contact_id = contacts.id",
        "LEFT JOIN contact_postalcards ON contact_postalcards.contact_id = contacts.id"
      ],
      :group => "companies.id"

      list.each do |item|
        p item.company_name, item.email_count, item.letter_count, item.postalcard_count
      end

:group=>选项的作用是什么?这会给我一个组内的总数吗(我想类似于sql group,对吧?)当company\u name是Contact的一个属性时,我如何按company\u name进行搜索,每个ContactEmail都属于Contact\u“?我可以为每个ContactEmail、ContactLetter(也是公司名称)创建一个虚拟属性吗?我如何跨所有型号(ContactEmail、ContactLetter等)进行查询?”
:group=>company\u name
与SQL中的相同,但从其他答案中我发现您更应该使用
:group=>“company\u id”
。正如我所说,在一个查询中执行此操作是过分的,但您可以在Fullware的答案中看到此操作的代码。我只想用最简单的方法来执行此操作……company\u name btw是con中的一个虚拟属性tact,它有一种归属关系……如果我想引用,例如,在ContactEmail模型中找到的其他信息,我不会,对吗?计数器缓存只是一个聚合数?是的,没错。你仍然可以在每个联系人上访问他们的联系人电子邮件,但不需要在内部对每个联系人进行额外查询。我如果您对要在聚合列上显示的信息类型有一些详细信息,我们可能会进一步帮助您。PS.可能值得考虑一下,除非您希望同时将所有4个表的所有内容加载到内存中。对于动态增长的表,通常避免这样做。同意。因此,让我们我想,我的问题显示了我现在想要显示的内容,所以我使用计数器缓存可以工作…除了我需要能够按日期过滤。然后,根据定义,该数字将动态变化。对吗?相同的输出已填充了样本数据…但总体结构仍然相同(按公司分组的联系人电子邮件记录总数(这些可能是同一联系人的,顺便说一句)…谢谢!嗨,谢谢---对不起,我有点迷路了…我如何使用.count方法?我一直在玩