2016-12-20 12 views
1

나는 쿼리 생성을 위해 Arels을 사용하고 있습니다. 이 쿼리에서는 generate_series 함수를 사용합니다. 여기 내 코드는 다음과 같습니다.레일즈 ActiveRecord Arels : 지원되지 않는 인수 유형 : 문자열. 대신 Arel 노드를 구축하십시오

def generate_series 
     Arel::Nodes::NamedFunction.new('GENERATE_SERIES', [start_date, end_day, '1 day']) 
    end 

def start_date 
     Arel::Nodes::SqlLiteral.new(<<-SQL 
     CASE WHEN DATE_PART('hour', NOW() AT TIME ZONE 'ICT') < #{Time.now - 3days} THEN (CURRENT_DATE - INTERVAL '14 days') ELSE (CURRENT_DATE - INTERVAL '13 days') END 
     SQL 
    ) 
    end 

    def end_date 
     Arel::Nodes::SqlLiteral.new(<<-SQL 
     CASE WHEN DATE_PART('hour', NOW() AT TIME ZONE 'ICT') < #{Time.now} THEN (CURRENT_DATE - INTERVAL '1 day') ELSE CURRENT_DATE END 
     SQL 
    ) 
    end 

generate_series.to_sql으로 테스트를 시도합니다.

Arel::Visitors::UnsupportedVisitError: Unsupported argument type: String. Construct an Arel node instead.

내가 테스트를 위해 짧은 내 코드를 시도 :

def generate_series 
     Arel::Nodes::NamedFunction.new('GENERATE_SERIES', ['19/11/2012', '20/11/2012', '1 day']) 
end 

문제는 동일 나는 예외를 만난다. 이 문제를 어떻게 해결할 수 있는지 말해주십시오.

답변

3

마지막 매개 변수는 Arel::Nodes이어야합니다. 따라서 Arel::Nodes:SqlLiteral1 day을 입력해야합니다. 여기에 업데이트됩니다 코드 : '1 day' :

def generate_series 
     Arel::Nodes::NamedFunction.new('GENERATE_SERIES', 
      [start_date, end_date, Arel::Nodes::SqlLiteral.new('\'1 day\'')] 
    ) 
end 

당신은 또한 괄호 안에 1 day, 즉 포장해야한다고 지적했다.

GENERATE_SERIES(start, stop, 1 day) 

그러나 실제 쿼리를해야합니다 :이 작업을 수행하지 않는 경우 때문에, 생성 된 쿼리가 될 것입니다

def generate_series 
     Arel::Nodes::NamedFunction.new('GENERATE_SERIES', 
      [start_date, end_date, Arel::Nodes.build_quoted('1 day')] 
    ) 
end 

:

GENERATE_SERIES(start, stop, '1 day') 
0

당신은 리터럴을 인용 Arel::Nodes.build_quoted을 사용할 수 있습니다 이것의 장점은 Arel::Nodes::SqlLiteral처럼 따옴표를 포함하고 수동으로 이스케이프하는 것을 기억할 필요가 없다는 것입니다.