2017-11-29 5 views
0

brakeman gem (Ruby on Rails 코드에서 발생할 수있는 보안 문제를 식별)과 함께 작업하고 있습니다. 조인, 그룹 및 선택을 사용하는 범위가 있으며 쿼리의 선택 부분을 업데이트해야합니다. 이 범위는 다음과 같습니다. 제품 모델에이 범위의 내용을 넣을 것입니다. 이제rails (QueryMethods)의 SQL select 쿼리에 날짜 매개 변수 전달

Product.joins('LEFT JOIN orders ON orders.product_id = products.id') 
    .group('products.id') 
    .select(
    "SUM(CASE WHEN orders.order_at BETWEEN '#{start_date}' AND '#{end_date}'" \ 
    " THEN orders.qty ELSE 0 END) as qty, products.*" 
) 

내가 그것은 나에게 내가 또한 그룹과 가진 몇 가지 다른 방법을 시도했지만 그것을 위해 일하지 않았다 ?이 구문 오류를 제공이

Product.joins('LEFT JOIN orders ON orders.product_id = products.id') 
    .group('products.id') 
    .select(
    "SUM(CASE WHEN orders.order_at BETWEEN ? AND ?" \ 
    " THEN orders.qty ELSE 0 END) as qty, products.*", 
    '#{start_date}', 
    '#{end_date}' 
) 

같은 쿼리를 변경하려고하면 나를. 레일과 함께 Postgres SQL을 사용하고 있습니다. 4.1.8
나는 이것을 달성 할 수있는 방법이 있습니까? 미리 감사드립니다.

당신은 ? 구문을 사용하는 것이 맞다 오류

PG::SyntaxError: ERROR: syntax error at or near "?"
LINE 1: SELECT SUM(CASE WHEN orders.order_at BETWEEN ? AND ? AND ord

+0

더 충분한 정보가 없습니다. 또한 [여기] (https://stackoverflow.com/questions/47531438/i-want-to-use-query-in-rails-just-like/47531725#47531725) 비슷한 무인 질문이 있습니다. –

답변

0

이지만, 그것의 select 필요 부분에 대한 전화는 intead where를 호출 속으로 분할합니다.

또한 날짜를 문자열 (예 : '#{start_date}')로 변환하고 있습니다. 따라서 호출 된 메소드가 값을 날짜로 처리하고 형식화 할 수 없게됩니다. 대신 원시 날짜 (예 : start_date) 만 전달하면됩니다.

Product 
    .joins('LEFT JOIN orders ON orders.product_id = products.id') 
    .where('orders.order_at BETWEEN ? AND ?', start_date, end_date) 
    .select("SUM(orders.qty) as qty, products.*") 
    .group('products.id') 

는 또한 daino3의 대답 (.where(orders: {order_at: start_date..end_date}))에 따라 where 전화를 다시 할 수있다.

추론

이 직접 where (또는 관련)에 있지 포함 매개 변수에 대한 중요 호출합니다. 이렇게하면 원격 사용자가 모든 유형의 위험한 호출이 데이터베이스에서 수행되는 모든 임의의 문자열을 잠재적으로 넣을 수 있기 때문에 코드를 SQL Injection이라는 주요 보안 위험 요소까지 열 수 있습니다.

그런 이유로 where("various sql things #{parameter}") 대신 항상 where('various sql things ?', parameter)을 사용해야합니다.

이와 같이 Rails SQL 호출에 매개 변수를 전달하는 것에 대한 자세한 내용은 official Rails Guide on the Active Record Query Interface을 확인하십시오.

+0

'총합, 제품. *, '2017-11-28 05 : 00 : 00.000000', '2017-11-29 04 :'로 합계를 선택하면 SUM이 표시됩니다 (orders.order_at와 상품 사이에 orders.qty ELSE 0 END) 59 : 59.999999 'FROM "products"LEFT JOIN 주문은 orders.product_id = products.id GROUP BY products.id' 생성 된 쿼리이며 동일한 오류가 있습니다. 내 생각 엔? 날짜로 대체해야하지만 그렇지 않은데 이유를 모르겠습니다. – Manishh

+0

대개 올바른 일이지만, 불행하게도'select' 메소드는 매개 변수를 사용하지 않으므로 문자열에 삽입하기 전에 직접 위생 처리를하거나 쿼리를 구성하는 다른 방법을 찾아야합니다 (예 : @ daino의 답변이 어떻게 표시되는지). –

+0

오, 예 -'select' 대신'where'를 사용하면이를 수정해야합니다. –

1

난 당신이 또한 어디 절과 CASE 문을 제거 할 수 믿습니다

checkout range conditions

Product 
    .joins('LEFT JOIN orders ON orders.product_id = products.id') 
    .where(orders: {order_at: start_date..end_date}) # range condition 
    .group('products.id') 
    .select("SUM(orders.qty) as qty, products.*")