이 코드를 원시 SQL로 변환하고 레일에서 사용하려면 어떻게해야합니까? heroku에이 코드를 배포 할 때 요청 시간 초과 오류가 발생합니다. raw 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 쿼리 결과입니다.
답변
나는 이것이 오래되었다는 것을 알고있다 … 그러나 나는 오늘 같은 문제가 있었고 해결책을 찾았다.
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
출처 :
답변
을 사용하여 원시 쿼리를 실행할 수 있습니다 ActiveRecord
. 그리고 나는 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)
답변
두 테이블 모두에 대해 단일 쿼리를 갖도록 SQL을 지시 할 수 있습니다. 이 예제가 필요를 지정하지 않았더라도 사람들이 변수를 문자열 자체에 직접 넣지 않도록 (예 : 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
입니다. 포스트 그레스를 사용하는 경우 그리고 당신은 예를 들어, 기본 준비된 문을 사용하여 준비된 문을 준비 raw_connection 수행 할 수 있습니다, 그리고에 설명 된대로 exec_prepared https://stackoverflow.com/a/13806512/178651
또한 원시 SQL 조각을 ActiveRecord 관계형 쿼리 ( http://guides.rubyonrails.org/active_record_querying.html)
및 연관, 범위 등으로 넣을 수 있습니다. ActiveRecord 관계형 쿼리를 사용하여 동일한 SQL을 구성 할 수 있습니다. Ernie가 http://erniemiller.org/2010/03/28/advanced-activerecord-3-queries-with-arel/ 에서 언급 한 ARel . 물론 다른 ORM, 보석 등도 있습니다.
이것이 많이 사용될 것이며 인덱스를 추가해도 다른 성능 / 자원 문제가 발생하지 않으면 payment_details.created_at 및 payment_errors.created_at에 대한 인덱스를 DB에 추가하십시오.
많은 레코드가 있고 모든 레코드가 한 번에 나타나지 않아도되는 경우 페이지 매김 사용을 고려하십시오.
페이지를 매길 필요가있는 경우, payment_details 및 payment_errors 테이블을 결합한 payment_records라는 뷰를 DB에 먼저 작성한 다음 뷰에 대한 모델 (읽기 전용)을 작성하십시오. 일부 DB는 구체화 된 뷰를 지원하므로 성능에 좋습니다.
또한 Rails 서버 및 DB 서버, 구성, 디스크 공간, 네트워크 속도 / 대기 시간 등의 하드웨어 또는 VM 사양, 근접성 등을 고려하고 그렇지 않은 경우 Rails 앱과 다른 서버 / VM에 DB를 배치하는 것을 고려하십시오. .
답변
나는 작업 할 exec_query
의 ActiveRecord
이 객체로 변신 쿼리의 매핑을 반환하기 때문에 피사체가 원시 SQL 때 그래서 객체로 반복하는 매우 실용적이고 생산적인 도착, 클래스입니다.
예:
values = ActiveRecord::Base.connection.exec_query("select * from clients")
p values
이 완전한 쿼리를 반환하십시오.
[{"id": 1, "name": "user 1"}, {"id": 2, "name": "user 2"}, {"id": 3, "name": "user 3"}]
값 목록 만 가져 오려면
p values.rows
[[1, "user 1"], [2, "user 2"], [3, "user 3"]]
필드 열만 가져 오려면
p values.columns
["id", "name"]
답변
예를 들어 조건에서 함수를 호출하려는 경우 원시 SQL을 ActiveRecord 조건과 혼합 할 수도 있습니다.
my_instances = MyModel.where.not(attribute_a: nil) \
.where('crc32(attribute_b) = ?', slot) \
.select(:id)