RoR ActiveRecord find_by_sql Вопрос - PullRequest
       23

RoR ActiveRecord find_by_sql Вопрос

0 голосов
/ 08 октября 2009

Я хочу предвосхитить этот вопрос, заявив, что я довольно новичок в разработке на Ruby, однако лично я посвятил себя попыткам найти ответы самостоятельно, а не прихотливым вопросам на форумах. При этом это мой первый официальный "пост", и я приложил все усилия, чтобы быть максимально точным и лаконичным в своем сообщении.

У меня есть база данных MSSQL 2005, к которой я подключаюсь, используя RoR ActiveRecord и RubyGems ADO.

В моем базовом классе AR я выполняю оператор find_by_sql, который выполняет многотабличный оператор SELECT. Мой запрос выполняется должным образом, и я подтвердил, что возвращаемые данные верны.

Моя цель:

Мне нужно запросить базу данных MSSQL 2005, а затем вывести данные, которые возвращаются в файл .csv.

Мой план для достижения этой цели:

  1. Использование ruby ​​gems и ADO для подключения к базе данных MSSQL
  2. Использование Ruby AR для запроса базы данных с использованием функции поиска по sql (в зависимости от характера запроса)
  3. Используйте Ruby FasterCSV, чтобы извлечь данные и вывести их в файл .csv.

Текущий сценарий:

Я могу успешно подключиться к базе данных и запросить данные с помощью AR.

Проблема:

После выполнения запроса find-by-sql AR возвращает данные в виде массива хэшей. Как я уже говорил ранее, я новичок в AR и развиваюсь в RoR уже несколько месяцев. Поэтому я не знаю, как получить доступ к атрибутам массива.

Вот что у меня есть:

require 'rubygems'
require 'activerecord'
require "fastercsv"


ActiveRecord::Base.pluralize_table_names = false

ActiveRecord::Base.establish_connection(
    :adapter => 'sqlserver',
    :mode => 'ODBC',
    :dsn => 'xxxx',
    :database => 'xxxx',
    :username => 'blah',
    :password => 'blahblah',
    :host => 'server'
)

class Dp_display < ActiveRecord::Base
    od30 = Dp_display.find_by_sql("SELECT dd.acct_no, dd.cur_bal, dd.od_dt, ra.email_1
    FROM dp_display dd, rm_acct ra
    WHERE dd.rim_no = ra.rim_no and dd.cur_bal < -10 and dd.class_code = 125 and 
    dd.od_dt = convert(varchar, getdate()-30,101)
    ORDER BY dd.od_dt desc");

    #testing od30 returning values successfully
    puts od30

Результат:

Когда я смотрю на od30, все данные возвращаются правильно. Данные выглядят так (перечисляются только первые элементы массива):

    od30 = Array (2 elements)
      +[0] = {Dp_display}#<Dp_display:0x7667d74>
          +@attributes = Hash (4 elements)
             +'acct_no'-> 1122334455
             +'email_1'-> whodat@where.com
             +'cur_bal'-> -333.55
             +'od_dt'-> 2009-09-08 00:00:00.000
      +[1] = {Dp_display}#<Dp_display:0x7667d10>

Используя FasterCSV, я выполняю следующее:

    FasterCSV.open("c://file30.csv", "w") do |csv|
      csv << od30

CSV-файл успешно создан, и когда я его открываю, он содержит только:

<Dp_display:0x7667d74>

Я пытаюсь получить:

1122334455, whodat @ where.com, -333,55,2009-09-08 00: 00: 00.000

В целях обучения / тестирования я попытался получить доступ к элементам массива, используя множество различных функций массива, включая model.attributes, each_index, flatten, а затем поместить результат. К сожалению, я не могу понять это.

В любом случае, я приду к тому же результату:

Опять же, я знаю, что через некоторое время я мог бы придумать сложное решение, но сейчас я хочу попытаться сделать его простым (поскольку я новичок в разработке и пытаюсь выучить небольшие шаги).

Любая помощь будет принята с благодарностью (даже если просто направить меня в правильном направлении!).

Спасибо.

Ответы [ 2 ]

1 голос
/ 08 октября 2009

find_by_sql все равно будет пытаться отобразить ваши результаты на объекты, в вашем случае объекты Dp_display. Поскольку они являются объектами ActiveRecord, вы можете получить доступ к столбцам, которые они возвращали, как к любому атрибуту, но любые производные столбцы, которые не существуют в таблице, будут доступны только для чтения.

Похоже, вы пытаетесь сбросить массив объектов вместо каждого объекта самостоятельно. Попробуйте что-то вроде этого:

FasterCSV.open("c://file30.csv", "w") do |csv|
  csv << ['here', 'are', 'my', 'headers']
  od30.each |o|
     csv << [o.acct_no, o.email_1, o.cur_bal, o.od_dt]
  end
end

Это не в моей голове, возможно, есть более простой способ сделать это, сопоставив ключи заголовка с атрибутами. Удачи!

Peer

0 голосов
/ 08 октября 2009

Или просто

FasterCSV.open("c://file30.csv", "w") do |csv|
  od30.each |o|
     csv << o
  end
end

http://fastercsv.rubyforge.org/

...