0

我有几个类似的模型 ContactEmail、ContactLetter 等等。

每一个belongs_to联系人

每个联系belongs_to一个公司

所以,我所做的是为 ContactEmail 创建一个虚拟属性:

  def company_name
    contact = Contact.find_by_id(self.contact_id)

    return contact.company_name

  end

问题:如果我有一组 ContactEmails 对象(例如,来自 find(:all) 方法),如何获得所有 company_name 的简单列表(不重复)?

例如,当我尝试使用统计信息 gem 搜索 ContactEmail.company_name 时,我收到一条错误消息,指出 company_name 不是 ContactEmail 的列。

4

1 回答 1

0

假设您的ContactEmail集合在@contact_emails (未经测试)

@contact_emails.collect { |contact_email| contact_email.company_name }.uniq

不过,您不需要为此目的使用虚拟属性。ActiveRecord 会根据外键自动建立关系,因此您可以将该company_name方法从 ContactEmail 模型中取出并执行以下操作:

@contact_emails.collect { |contact_email| contact_email.contact.company_name }.uniq

性能可能是大型集合的考虑因素,因此如果这是一个问题,您可能需要使用更复杂的 SQL 查询。

编辑 回答你的第二个问题

如果company_name是一列,您可以执行以下操作:

ContactEmail.count(:all, :joins => :contact, :group => 'contact.company_name')

在虚拟属性上,我认为您必须检索整个集合并使用 Ruby (untested)

ContactEmail.find(:all, :joins => :contact, :select => 'contacts.company_name').group_by(&:company_name).inject({}) {|hash,result_set| hash.merge(result_set.first=>result_set.last.count)}

但这对下一个负责维护您的系统的人来说不是很好——因此您最好制定.count版本的查询语法并引用列本身。

于 2010-08-17T08:15:30.220 回答