【问题标题】:How can I get a unique :group of a virtual attribute in rails?如何在rails中获得唯一的:组虚拟属性?
【发布时间】:2010-08-17 05:00:18
【问题描述】:

我有几个类似的模型 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 的简单列表(不重复)? p>

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

【问题讨论】:

    标签: ruby-on-rails join virtual-attribute


    【解决方案1】:

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

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

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

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

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

    编辑 回答你的第二个问题

    如果company_name 是一列,你可以这样做:

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

    关于虚拟属性,我认为您必须检索整个集合并使用 Ruby (未测试)

    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 版本的查询语法并引用该列本身。

    【讨论】:

    • 我明白了...company_name 也是contact 的虚拟属性,但我认为没关系。
    • 是否有办法,因为无论如何我都必须通过 company_names,来计算属于给定 company_name 内的实例总数,有点像使用 GROUP?
    • company_name 不是联系人列。它也是一个虚拟属性。所以这意味着我必须做那么长的事情?
    • 我的建议是不要使用“巨大的长的东西”,因为它有点晦涩,并且可能对性能不利。最好的办法是找出虚拟属性的实际列和表,然后编写 Rails 查找方法来进行查询,或者直接使用 SQL 并使用.find_by_sql。如果您使用适当的模型/表格在 SO 上发布新问题,我敢打赌您会得到一个很好的答案。
    • 好的,这回答了问题:我可以通过 Contactemail.contact.company.name 访问公司名称。谢谢...现在的问题是如何显示每家公司的计数?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-11
    • 2013-01-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多