Использование RoR с устаревшей таблицей, использующей E-A-V - PullRequest
1 голос
/ 21 сентября 2009

Мне нужно подключиться к устаревшей базе данных и извлечь подмножество данных из таблицы, которая использует модель сущности-атрибут-значение для хранения информации о контакте. Таблица выглядит следующим образом:

subscriberid     fieldid     data
1                2           Jack
1                3           Sparrow
2                2           Dan
2                3           Smith

где fieldid - это внешний ключ к таблице fields, в которой перечислены настраиваемые поля, которые может иметь данный клиент (например, имя, фамилия, телефон). Используемый SQL довольно сложен, так как я должен присоединить таблицу к себе для каждого поля, которое я хочу вернуть (в настоящее время мне нужно 6 полей), а также присоединиться к основному списку контактов, который основан на текущем пользователе.

SQL выглядит примерно так:

select t0.data as FirstName, t1.data as LastName, t2.data as SmsOnly
  from subscribers_data t0 inner join subscribers_data t1 
    on t0.subscriberid = t1.subscriberid
  inner join subscribers_data t2 
    on t2.subscriberid = t1.subscriberid
  inner join list_subscribers ls 
    on (t0.subscriberid = ls.subscriberid and t1.subscriberid = ls.subscriberid)
  inner join lists l
    on ls.listid = l.listid
  where l.name = 'My Contacts'
    and t0.fieldid = 2 
    and t1.fieldid = 3;

Как мне решить эту проблему с моим приложением RoR? Я хотел бы абстрагироваться от этого и по-прежнему иметь возможность использовать обычные «точечные обозначения» для извлечения атрибутов. К счастью, в обозримом будущем данные доступны только для чтения.

Ответы [ 2 ]

1 голос
/ 21 сентября 2009

Это именно то, для чего был разработан #find_by_sql. Я бы переопределил #find, чтобы сделать то, что вам нужно, что-то вроде этого:

class Contact < ActiveRecord::Base
  set_table_table "subscribers_data"

  def self.find(options={})
    find_by_sql <<EOS
      select t0.data as FirstName, t1.data as LastName, t2.data as SmsOnly
        from subscribers_data t0 inner join subscribers_data t1 
          on t0.subscriberid = t1.subscriberid
        inner join subscribers_data t2 
          on t2.subscriberid = t1.subscriberid
        inner join list_subscribers ls 
          on (t0.subscriberid = ls.subscriberid and t1.subscriberid = ls.subscriberid)
        inner join lists l
          on ls.listid = l.listid
        where l.name = 'My Contacts'
          and t0.fieldid = 2 
          and t1.fieldid = 3;
    EOS
  end
end

Экземпляры Contact будут иметь атрибуты #FirstName и #LastName. Вы можете переименовать их так, как ожидает AR, так что #first_name и #last_name будут работать. Просто измените предложения AS вашего SELECT.

0 голосов
/ 22 сентября 2009

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

...