如何根据模型上的虚拟属性返回的值搜索整个模型?

Posted

技术标签:

【中文标题】如何根据模型上的虚拟属性返回的值搜索整个模型?【英文标题】:How do I search an entire model based on the value returned by a virtual attribute on that model? 【发布时间】:2019-04-14 17:43:57 【问题描述】:

我有一个模型Property,并且我有一个定义如下的虚拟属性:

  def uid_type
    if mls? && mls.to_i != 0
      "MLS"
    elsif property_identifier? && property_identifier.to_i != 0
      "PID"
    else
      "ID"
    end
  end

如果我有一个属性p,当我查询那个虚拟属性时,我看到的是这样的:

> p.uid_type
 => "MLS" 

基本上,我想做的是在我的模型上创建一个范围以返回所有具有uid_type == 'MLS' 的属性。

我该怎么做?

编辑 1

如果我试试这个:

Property.where('properties.uid_type == "MLS"').count
   (4.6ms)  SELECT COUNT(*) FROM "properties" WHERE (properties.uid_type == "MLS")
ActiveRecord::StatementInvalid: PG::UndefinedColumn: ERROR:  column properties.uid_type does not exist
LINE 1: SELECT COUNT(*) FROM "properties"  WHERE (properties.uid_typ...

【问题讨论】:

【参考方案1】:

您必须编写自己的范围,ActiveRecord 对自定义方法没有多大帮助。

scope :with_mls_uid_type, ->  where.not(mls: [nil, '']) 

这将转化为:

SELECT "properties".* 
FROM "properties" 
WHERE ("properties"."mls" IS NOT NULL) 
AND ("properties"."mls" != '')

如果您的标签是正确的并且您仍在使用 Rails 3.2,那么您将没有 .not 并且您必须这样做:

where("mls IS NOT NULL AND mls != ''")

【讨论】:

我正要询问 Rails 3.2 和 not。因此,我尝试了您的示例,但出现以下错误:> Property.where("mls IS NOT NULL AND mls !=0").count (1.3ms) SELECT COUNT(*) FROM "properties" WHERE (mls IS NOT NULL AND mls !=0) ActiveRecord::StatementInvalid: PG::UndefinedFunction: ERROR: operator does not exist: character varying <> integer HINT: No operator matches the given name and argument type(s). You might need to add explicit type casts. 顺便说一句。如果mls 是一个字符串,你确定你知道mls.to_i != 0 是如何工作的吗? "5foo".to_i == 5,但"foo".to_i == 0。这对于范围很重要,因为在 PostgreSQL 中编写并不那么简单,并且可能不是您想要的。 我真的不确定。这是我正在接管的遗留代码库,所以我现在正在挖掘所有内容。但我会对此进行调查并根据需要进行适当的错误处理。感谢您的回答和反馈!

以上是关于如何根据模型上的虚拟属性返回的值搜索整个模型?的主要内容,如果未能解决你的问题,请参考以下文章

如何自动解析 Sails.js 路由上的模型属性?

Rails 虚拟属性搜索或 sql 组合列搜索

有没有办法不使用 Kohana 中的子模型覆盖整个属性?

如何生成属性名称,并在 Rails 模型中获取它们的值

Laravel 通过属性获得雄辩的查询构建器关系

如何在 C# 模型类中设置数组属性的值