在Rails中,我有时想用MySQL进行查询,这对于ActiveRecord方法来说太复杂了。所以我通常会做以下操作来获取一系列哈希值:
query = "SELECT * FROM ..."
result = ActiveRecord::Base.connection.exec_query.to_a
通常情况下,我可以侥幸逃脱,但有时我仍然需要一个模型实例数组,以便我可以将它们用于CRUD。
在那种情况下,我试过这个:
result.map{|u| User.new(u)}
这一点很好,直到我尝试创建,保存或更新。当发生这种情况时,我收到一个错误,告诉我已经存在具有相同ID的记录。
不知何故,ActiveRecord已经知道如何使用它能够构造的查询来执行此操作。我怎样才能做同样的事情并使其成为可以将一个复杂的原始查询转换为一组模型实例,这些实例将改变表而不是试图插入和失败?
答案 0 :(得分:6)
使用find_by_sql例如
User.find_by_sql("SELECT * FROM user...")
执行result.map{|u| User.new(u)}
的麻烦在于,这会创建新的User
对象,其属性取自exec_query
返回的哈希值,但这些属性被视为新的未保存的Active Record模型,因此会发生冲突如果您尝试保留它们,请使用现有记录。
也就是说,Active Record查询界面非常灵活,因此值得发布一些您需要查询的示例,看看是否可以在不使用原始SQL的情况下建模这些查询。
答案 1 :(得分:1)
您可以通过调用类中的find_by_sql
找到对象:
User.find_by_sql('select users.* from users ... ')
或者,您必须find来自您在查询中识别的ID的用户:
query = "SELECT id FROM users WHERE..."
user_ids = ActiveRecord::Base.connection.exec_query.to_a
User.find(user_ids)