Rails原始的SQL例子

我怎样才能将此代码转换为原始的SQL和在rails中使用? 因为当我在heroku中部署这段代码时,有一个请求超时error.I认为这将更快,如果我使用原始的SQL。

@payments = PaymentDetail.joins(:project).order('payment_details.created_at desc') @payment_errors = PaymentError.joins(:project).order('payment_errors.created_at desc') @all_payments = (@payments + @payment_errors) 

你可以这样做:

 sql = "Select * from ... your sql query here" records_array = ActiveRecord::Base.connection.execute(sql) 

records_array然后将是你的sql查询在你可以迭代的数组的结果。

我知道这是旧的…但是我今天有同样的问题,并find一个解决scheme:

 Model.find_by_sql 

如果你想实例化结果:

 Client.find_by_sql(" SELECT * FROM clients INNER JOIN orders ON clients.id = orders.client_id ORDER BY clients.created_at desc ") # => [<Client id: 1, first_name: "Lucas" >, <Client id: 2, first_name: "Jan">...] 

 Model.connection.select_all('sql').to_hash 

如果你只想散列值:

 Client.connection.select_all("SELECT first_name, created_at FROM clients WHERE id = '1'").to_hash # => [ {"first_name"=>"Rafael", "created_at"=>"2012-11-10 23:23:45.281189"}, {"first_name"=>"Eileen", "created_at"=>"2013-12-09 11:22:35.221282"} ] 

结果对象:

select_all返回一个result对象。 你可以用它做魔术。

 result = Post.connection.select_all('SELECT id, title, body FROM posts') # Get the column names of the result: result.columns # => ["id", "title", "body"] # Get the record values of the result: result.rows # => [[1, "title_1", "body_1"], [2, "title_2", "body_2"], ... ] # Get an array of hashes representing the result (column => value): result.to_hash # => [{"id" => 1, "title" => "title_1", "body" => "body_1"}, {"id" => 2, "title" => "title_2", "body" => "body_2"}, ... ] # ActiveRecord::Result also includes Enumerable. result.each do |row| puts row['title'] + " " + row['body'] end 

资料来源:

  1. ActiveRecord – SQL查找 。
  2. Ruby on Rails – 活动logging结果 。

您可以直接使用SQL来对这两个表进行单个查询。 我将提供一个清理过的查询示例,希望避免人们直接将variables放入string本身(SQL注入危险),即使这个例子没有指定它的必要性:

 @results = [] ActiveRecord::Base.connection.select_all( ActiveRecord::Base.send(:sanitize_sql_array, ["... your SQL query goes here and ?, ?, ? are replaced...;", a, b, c]) ).each do |record| # instead of an array of hashes, you could put in a custom object with attributes @results << {col_a_name: record["col_a_name"], col_b_name: record["col_b_name"], ...} end 

编辑 :正如Huy所说,一个简单的方法是ActiveRecord::Base.connection.execute("...") 。 另一种方法是ActiveRecord::Base.connection.exec_query('...').rows 。 你可以使用本地准备的语句,例如,如果使用postgres,准备好的语句可以使用raw_connection,prepare和exec_prepared完成,如https://stackoverflow.com/a/13806512/178651

您还可以将原始SQL片段放入ActiveRecord关系查询中: http : //guides.rubyonrails.org/active_record_querying.html以及关联,作用域等等。您可以使用ActiveRecord关系查询构build相同的SQL,并且可以用艾尔在Ernie在http://erniemiller.org/2010/03/28/advanced-activerecord-3-queries-with-arel/中提到。; 当然还有其他的ORM,gem等

如果这将被大量使用,并且添加索引不会导致其他性能/资源问题,请考虑在数据库中为payment_details.created_at和payment_errors.created_at添加索引。

如果大量的logging,而不是所有的logging需要立即出现,考虑使用分页:

如果您需要分页,请考虑在DB中首先创build一个名为payment_records的视图,该视图组合了payment_details和payment_errors表,然后为该视图创build一个模型(将为只读模式)。 一些数据库支持实体化视图,这可能是性能的一个好主意。

还要考虑Rails服务器和数据库服务器,configuration,磁盘空间,networking速度/等待时间等等的硬件或虚拟机规格,接近度等。如果你还没有,考虑把数据库放在不同的服务器/虚拟机上,等等。 。

您可以使用ActiveRecord执行原始查询。 我会build议去SQL块

 query = <<-SQL SELECT * FROM payment_details INNER JOIN projects ON projects.id = payment_details.project_id ORDER BY payment_details.created_at DESC SQL result = ActiveRecord::Base.connection.execute(query)