Arel生成不同的SQL输出

时间:2013-09-06 20:29:31

标签: ruby-on-rails ruby activerecord arel

我正在为使用Arel的Rails编写一个gem。我遇到了一个情况,子节点生成的输出根据输出的生成方式而有所不同。以下是测试用例。这是一个错误还是我做错了什么?

  it 'should generate the same output' do
    def ts_language; 'english'; end

    def searchable_columns; [:id, :name]; end

    def ts_column_sets
      column_sets = if searchable_columns[0].is_a?(Array)
        searchable_columns.map do |array|
          array.map { |c| Table.new(:users)[c] }
        end
      else
        searchable_columns.map { |c| Table.new(:users)[c] }.map { |x| [x] }
      end
    end

    def ts_vectors
      ts_column_sets.map do |columns|
        coalesce = columns[1..-1].inject(columns[0]) do |memo, column| 
          Arel::Nodes::InfixOperation.new('||', memo, column)
        end
        coalesce = Arel::Nodes::InfixOperation.new('::', Arel::Nodes::NamedFunction.new('COALESCE', [coalesce, '']), Arel::Nodes::SqlLiteral.new('text'))
        Arel::Nodes::NamedFunction.new('to_tsvector', [ts_language, coalesce])
      end
    end

    def ts_query(query)
      querytext = query.is_a?(Array) ? query.map(&:to_s).map(&:strip) : query.to_s.strip.split(" ")
      querytext = querytext[1..-1].inject(querytext[0]) { |memo, c| memo +  ' & ' + c }
      querytext << ':*'
      querytext = Arel::Nodes::InfixOperation.new('::', querytext, Arel::Nodes::SqlLiteral.new('text'))
      Arel::Nodes::NamedFunction.new('to_tsquery', ['english', querytext])
    end

    node = Arel::Nodes::InfixOperation.new('@@', ts_vectors[0], ts_query(0))
    assert_equal 'to_tsvector(\'english\', COALESCE("users"."id", 0) :: text)', node.left.to_sql
    assert_equal 'to_tsquery(\'english\', \'0:*\' :: text)', node.right.to_sql
    assert_equal 'to_tsvector(\'english\', COALESCE("users"."id", 0) :: text) @@ to_tsquery(0, \'0:*\' :: text)', node.to_sql
  end

该行

assert_equal 'to_tsquery(\'english\', \'0:*\' :: text)', node.right.to_sql

是正确的但行

assert_equal 'to_tsvector(\'english\', COALESCE("users"."id", 0) :: text) @@ to_tsquery(0, \'0:*\' :: text)', node.to_sql

导致错误,输出为:

'to_tsvector(\'english\', COALESCE("users"."id", 0) :: text) @@ to_tsquery(0, 0 :: text)'

0 个答案:

没有答案