2012-04-23 1 views
2

Доброго утра,Rails ActiveRecord - Уникальность и подстановки на массиве атрибуты

У меня есть модель Rails, в которой я в настоящее время сериализации массив информации. Две вещи, которые важны для меня:

  1. Я хочу, чтобы иметь возможность убедиться, что это уникальное (т.е. не может иметь две модели с тем же массивом)
  2. Я хочу, чтобы иметь возможность поиска существующих моделей этот хэш (в виде метода find_or_create_by).

Эта модель описывает «портфель» - то есть группу акций или облигаций. Массив - это описание того, какие ценные бумаги находятся внутри портфеля, и в каких весах. У меня также есть вторая модель, которая представляет собой группу портфелей (позволяет называть ее «Portcollection», чтобы все было просто). Коллекция имеет много портфелей, а портфель может быть во многих коллекциях. Другими словами:

class Portfolio 
    serialize :weights 
    has_and_belongs_to_many :portcollections 

class Portcollection 
    has_and_belongs_to_many :portfolios 

Когда я генерации «portcollection» Мне нужно построить кучу портфелей, которые я делаю программно (реализация не имеет значения). Построение портфеля - дорогостоящая операция, поэтому я пытаюсь проверить наличие первого. Я думал, что могу сделать это через find_or_create_by, но не имел большой удачи. Это мое текущее решение:

Class Portcollection 
    before_save :build_portfolios 

    def build_portfolios 
    …… 
    proposed_weights = …… 
    yml =proposed_weights.to_yaml 
    if port = Portfolio.find_by_weights(yml) 
     self.portfolios << port 
    else 
     self.portfolios << Portfolio.create!(:weights => proposed_weights) 
    end 
    …….. 
end 

Это действительно работает, но это довольно медленно. У меня такое чувство, потому что я конвертирую материал в YAML каждый раз, когда он запускается, когда я пытаюсь проверить существующий портфолио (это работает, вероятно, миллионы раз), и я ищу строку, в отличие от целое число. Однако у меня есть указатель на этот столбец.

Есть ли лучший способ сделать это? Несколько соображений передумали:

  • Рассчитать массив MD5 массива «весов» и сохранить в столбце базы данных. Мне все равно придется вычислять этот хэш каждый раз, когда я хочу найти массив, но у меня есть ощущение, что в базе данных будет проще индексировать & поиск?
  • Работа над перемещением из has_and_belongs_to_many в has_many => through и сохранение информации о массиве в виде столбцов базы данных. Таким образом, я мог бы попытаться разобраться в запросе к базе данных, которые могли бы проверить на уникальность, без YAML или сериализации ...

т.е. что-то вроде:

class Portfolio 
    has_many :portcollections, :through => security_weights 

class Portcollections 
    has_many :portfolios, :through => security_weights 

SECURITY_WEIGHTS 
id  portfolio_id  portcollection_id  weight_of_GOOG weight_of_APPLE …… 
1   14     15     0.4   0.3 

В случае, важно, что «вес "Массив будет выглядеть так:

[ [‘GOOG’, 0.4] , [‘AAPL’, 0.3] , [‘GE’, 0.3] ] 

Любая помощь будет принята с благодарностью. Пожалуйста, имейте в виду, я довольно любитель - программирование - это просто хобби для меня! Пожалуйста, извините меня, если я делаю что-нибудь действительно взломанное или отсутствует что-то очевидное.

Спасибо!

UPDATE 1

Я сделал некоторые исследования в 3.2 метод Rails «магазин», но это не кажется, ответ либо ...Он просто хранит объекты как JSON, что дает мне то же отсутствие возможности поиска, которое у меня есть сейчас.

ответ

2

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

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

+0

Спасибо за ответ Джоэл! Я боялся, что это будет ответ ... Когда вы говорите: «Храните отдельный хеш в своей колонке», я подумал, что это то, что делает сериализация. Вы имели в виду хранить хэш-атрибуты EACH в своей колонке? Будет ли модель объединения (как описано) хорошим местом для жизни? – Brandon

+1

Я бы добавил еще один столбец в той же модели, что и ваш магазин ключей/значений. Используйте хэш MD5, рассчитанный из значений, которые вы храните в ключе/значении для запроса. Rails делает «волшебство» с хранилищем ключей/значений, я бы не планировал его, если в будущих версиях рельсов произойдут некоторые изменения. –

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