简体   繁体   English

在 Rails 5 或 6 中为虚拟属性创建活动记录查询

[英]create active record query for virtual attribute in Rails 5 or 6

If I have a virtual attribute such as full_name , composed of first_name + " " + last_name , and I want to find users with User.where(full_name: "John Whoosiwhatsit") , how can I do this?如果我有一个虚拟属性,例如full_name ,由first_name + " " + last_name ,并且我想使用User.where(full_name: "John Whoosiwhatsit")查找用户,我该怎么做?

This was apparently not possible back in Rails 3 (or whatever was current 8 years ago) , but it seems like it may have been made possible since then.这在Rails 3(或任何 8 年前的当前版本)中显然是不可能的,但似乎从那时起就可以实现了。

And yes, I know that in the example given there are problems when you have "Anne Marie Van Der Moss", but the point of the question is about how to do this type of thing, not whether the particular example is a good idea or easy to implement well.是的,我知道在给出的示例中,当您使用“Anne Marie Van Der Moss”时会出现问题,但问题的重点在于如何做此类事情,而不是特定示例是否是一个好主意或易于实施。

User.select("users.*", "CONCAT(users.first_name, ' ', users.last_name) AS full_name")
    .where(full_name: "John Whoosiwhatsit")

This will work on MySQL, Postgres and SQLite (and probally more).这将适用于 MySQL、Postgres 和 SQLite(可能还有更多)。 ActiveRecord will map any aliased columns in the resulting rows from the query as attributes in the model. ActiveRecord 会将查询结果行中的任何别名列映射为模型中的属性。

Some dbs (like Oracle) don't let you use aliases in the WHERE clause so you would have to repeat the concatenation:某些数据库(如 Oracle)不允许您在 WHERE 子句中使用别名,因此您必须重复连接:

# Use an Enterprise DB they said. It will be fun they said.
User.select("users.*", "CONCAT(users.first_name, ' ', users.last_name) AS full_name")
    .where("CONCAT(users.first_name, ' ', users.last_name) = 'John Whoosiwhatsit'")

This has probally worked in almost every version since Rails AFAIK has always allowed you to revert to raw SQL if needed.这可能在几乎所有版本中都有效,因为 Rails AFAIK 总是允许您在需要时恢复到原始 SQL。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM