Rails ActiveRecord Arels:不支持的参数类型:字符串。改为构建 Arel 节点
Rails ActiveRecord Arels: Unsupported argument type: String. Construct an Arel node instead
我正在使用 Arels
创建查询。在此查询中,我使用 generate_series
函数。这是我的代码:
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
问题是一样的。请告诉我如何解决这个问题。
你的最后一个参数应该是 Arel::Nodes
。所以你应该把 1 day
包装成 Arel::Nodes:SqlLiteral
。这是更新的代码:
def generate_series
Arel::Nodes::NamedFunction.new('GENERATE_SERIES',
[start_date, end_date, Arel::Nodes::SqlLiteral.new('\'1 day\'')]
)
end
请注意,您还必须将 1 day
括在(单)引号内,即:'1 day'
。因为如果你不这样做,生成的查询将是:
GENERATE_SERIES(start, stop, 1 day)
但真正的查询应该是:
GENERATE_SERIES(start, stop, '1 day')
您可以使用 Arel::Nodes.build_quoted
来引用文字:
def generate_series
Arel::Nodes::NamedFunction.new('GENERATE_SERIES',
[start_date, end_date, Arel::Nodes.build_quoted('1 day')]
)
end
这样做的好处是您不必像使用 Arel::Nodes::SqlLiteral
那样记住包含和手动转义引号。
我正在使用 Arels
创建查询。在此查询中,我使用 generate_series
函数。这是我的代码:
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
问题是一样的。请告诉我如何解决这个问题。
你的最后一个参数应该是 Arel::Nodes
。所以你应该把 1 day
包装成 Arel::Nodes:SqlLiteral
。这是更新的代码:
def generate_series
Arel::Nodes::NamedFunction.new('GENERATE_SERIES',
[start_date, end_date, Arel::Nodes::SqlLiteral.new('\'1 day\'')]
)
end
请注意,您还必须将 1 day
括在(单)引号内,即:'1 day'
。因为如果你不这样做,生成的查询将是:
GENERATE_SERIES(start, stop, 1 day)
但真正的查询应该是:
GENERATE_SERIES(start, stop, '1 day')
您可以使用 Arel::Nodes.build_quoted
来引用文字:
def generate_series
Arel::Nodes::NamedFunction.new('GENERATE_SERIES',
[start_date, end_date, Arel::Nodes.build_quoted('1 day')]
)
end
这样做的好处是您不必像使用 Arel::Nodes::SqlLiteral
那样记住包含和手动转义引号。