ActiveRecord和编写原始查询之间有什么区别。 在哪种情况下,应该采用在rails app中编写原始查询。
答案 0 :(得分:4)
关键的区别在于,ActiveRecord可以通过使用更高级别的抽象来提高您的工作效率。
通过抽象出DBMS之间的一些差异,它还使您的代码更具可移植性。
如果您不注意ActiveRecord生成的查询,这种抽象是有代价的,可能会导致性能问题。
在哪种情况下应该采用在rails app中编写原始查询?
当需要完成手头的工作时。例如,这可以使用Postgres扩展ILIKE
:
# case insensitive search:
@user = User.where('users.name ILIKE ?', params[:name])
或者当您需要执行复杂的连接或其他性能关键操作时。像这个例子一样,每个父母获取一些相关记录。听起来很简单但在ActiveRecord中很难做到。
class Observation < ActiveRecord::Base
belongs_to :station
# ...
def self.pluck_from_each_station(limit = 1)
ActiveRecord::Base.connection.execute(%Q{
SELECT o.id
FROM stations s
JOIN LATERAL (
SELECT id, created_at
FROM observations
WHERE station_id = s.id -- lateral reference
ORDER BY created_at DESC
LIMIT #{limit}
) o ON TRUE
ORDER BY s.id, o.created_at DESC;
}).field_values('id')
end
end
最后,如果您不知道如何使用ActiveRecord执行操作,通常最好先编写一些带有测试支持的SQL,然后再返回并重构。
@users = User.where("occupation NOT IN(?)", params[:blacklist])) # @todo fix
然后你可以将其重构为:
@users.where.not(occupation: params[:blacklist])
答案 1 :(得分:0)
ActiveRecord大部分时间都会为您提供服务,但在某些情况下您需要编写原始sql。值得注意的是,ActiveRecord查询也可以以类似sql的方式编写。例如,您可以写:
User.where(name: "Person A")
或者您可以使用稍微类似SQL的语法编写它:
User.where("name = ?", "Person A")
User.where("name LIKE ?", "%Person A%")
您可能想要编写原始SQL的原因之一是当您尝试访问无法通过ActiveRecord方法访问的内容时,例如has_and_belongs_to_many
关联中的连接表。