Skip to content

Instantly share code, notes, and snippets.

@maia
Created June 15, 2009 16:06

Revisions

  1. maia created this gist Jun 15, 2009.
    82 changes: 82 additions & 0 deletions ActiveRecord::Base.select_values
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,82 @@
    class ActiveRecord::Base

    class << self

    def select_values(*args)
    options = args.extract_options!
    validate_find_options(options)
    set_readonly_option!(options)
    raise "select_values does not support the :include option" if options[:include]

    sql = construct_finder_sql(options)
    select_values_by_sql(options[:select].to_s, sql)
    end

    def select_value(*args)
    options = args.extract_options!
    validate_find_options(options)
    set_readonly_option!(options)
    raise "select_values does not support the :include option" if options[:include]

    sql = construct_finder_sql(options.update(:limit => 1))
    select_values_by_sql(options[:select].to_s, sql).first
    end

    def select_all(*args)
    options = args.extract_options!
    validate_find_options(options)
    set_readonly_option!(options)
    raise "select_values does not support the :include option" if options[:include]

    sql = construct_finder_sql(options)
    select_all_by_sql(sql)
    end

    def select_rows(*args)
    options = args.extract_options!
    validate_find_options(options)
    set_readonly_option!(options)
    raise "select_rows does not support the :include option" if options[:include]

    sql = construct_finder_sql(options)
    columns = options[:select].split(',').map(&:strip)
    columns = columns.map do |column|
    column.include?(" AS ") ? column[/AS (.+)/][3..-1] : column
    end
    select_rows_by_sql(columns, sql)
    end

    private

    def select_values_by_sql(column_name, sql)
    result = connection.select_values(sanitize_sql(sql))
    column = columns_hash[column_name]
    column ? result.map {|val| column.type_cast(val) } : result
    end

    def select_all_by_sql(sql)
    result = connection.select_all(sanitize_sql(sql))
    result.collect do |record|
    record.inject({}) do |memo, kv|
    column = self.columns_hash[kv[0]]
    memo[kv[0]] = column ? column.type_cast(kv[1]) : kv[1]
    memo
    end
    end
    end

    def select_rows_by_sql(columns, sql)
    result = connection.select_rows(sanitize_sql(sql))
    result.collect do |record|
    row = []
    record.each_with_index do |value, index|
    column = self.columns_hash[columns[index]]
    row << (column ? column.type_cast(value) : value)
    end
    row
    end
    end

    end

    end