2009-10-08 3 views
0

Я хочу предисловие к этому вопросу, заявив, что я довольно новичок в разработке Ruby, однако лично я посвятил себя самому самому найти ответы, а не причудливо задавать вопросы на форумах. Это, как говорится, это моя первая официальная «почта», и я сделал все попытки быть такими точными и лаконичными в моей публикации.RoR ActiveRecord find_by_sql Вопрос

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

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

Моя цель:

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

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

  1. Использование рубиновые камни & ADO для подключения к MSSQL DB
  2. Использование рубин AR для запросов к базе данных с помощью находку-на-SQL (в связи с характер запроса)
  3. Используйте Ruby FasterCSV для извлечения данных и сбрасывания их в CSV-файл.

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

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

Проблема:

После запроса находки-по-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> 
      [email protected] = Hash (4 elements) 
      +'acct_no'-> 1122334455 
      +'email_1'-> [email protected] 
      +'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 @ Whe re.com, -333.55,2009-09-08 00:00:00.000

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

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

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

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

спасибо.

ответ

1

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

Благодаря Peer! Это сработало отлично. Посмотрев на то, что вы рекомендовали, мне стало ясно, что я не рассматриваю элементы массива как объекты. Вместо этого я сам выгружал массив, а не его элементы. Спасибо, что помогли мне разобраться! –

0

Или просто

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

http://fastercsv.rubyforge.org/

+0

я могу видеть логику здесь, но когда я изменяю код, чтобы отразить это, я получаю ошибку: в «каждом»: нет блока заданного (LocalJumpError) Этой ошибка относится к линии, которая содержит: od30. каждый | o | Идентификатор RubyMine также указывает, что «o» не может быть разрешено для действительной цели. –

Смежные вопросы