2016-08-05 9 views
0

У меня есть приложение, которое требует использования шифрования для некоторых полей в базе данных. В настоящее время это реализуется с использованием проблемы, которая обрабатывает мелкие детали шифрования и управления полями для включенных классов. Важно, чтобы система могла определить программно, какие классы включают эту проблему, но даже более конкретно программно там должен быть хороший способ определить, какие поля зашифрованы.Ruby Альтернатива использованию переменных класса в ActiveSupport :: Концерн

Сегодня это реализуется, работая, используя переменные класса, как это:

module EncryptedFields 

    extend ActiveSupport::Concern 

    included do 
     @@encrypted_attributes ||= {} 
     @@encrypted_attributes[self.to_s] ||= [] 

     def self.encrypted attribute, options={} 

      @@encrypted_attributes[self.to_s] << attribute 

      ### Other stuff 
     end 
    end 
end 

В классе, как это:

class SomeEcryptedModel 

    include EncryptedFields 

    encrypted :field_name, options 
    encrypted :other_field_name, options 

    #etc 
end 

Класс переменной @@encrypted_attributes будет правильно захватывать хэш ключа - пары значений с включением имени класса в качестве ключа и массива зашифрованных атрибутов в качестве значения. Я рассмотрел использование системы регистрации для зашифрованных моделей для использования и «регистрации» себя и их атрибутов, но с этим связано гораздо больше накладных расходов, и на моей временной шкале я хотел бы начать с чего-то более простого, если он не слишком опасен ,

Это действительно нормально работает в моем текущем приложении, но у меня нет большого опыта с проблемами или переменными класса, поэтому я обеспокоен тем, сделал ли я серьезный просчет того, как это будет вести себя. Где здесь есть? Я был запрограммирован с тех пор, как начал работать с ruby ​​(не так давно), что переменные класса вообще избегают.

Меня уже укусили, потому что изначально я думал, что переменная класса @@encrypted_attributes будет переменной класса на включенном классе; это, очевидно, было не так. Каждая новая модель, которая включала бы ее, перезаписывала бы ее, поэтому я пришел к выводу, что эта переменная класса, по-видимому, была самой проблемой. По крайней мере, это поведение, которое я, кажется, наблюдаю. Это оказалось более желательным поведением в конце, потому что теперь я могу получить полный список зашифрованных моделей. У этого есть очевидное ограничение, что он может только вернуть список зашифрованных моделей и атрибутов для загруженных моделей.

Итак, мой вопрос:

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

Может быть, я просто стараюсь быть слишком умным, и мне нужно просто написать свой список? Спасибо за помощь!

ответ

2

Вы можете идти по этому пути в качестве альтернативы относиться подход:

module EncryptedFields 
    @encrypted_attributes ||= {} 

    def self.included(klass) 
    @encrypted_attributes[klass.name] ||= [] 
    klass.extend(ClassMethods) 
    end 

    def self.add(class_name, attribute) 
    @encrypted_attributes[class_name] << attribute 
    end 

    module ClassMethods 
    def encrypted(attribute, options={}) 
     EncryptedFields.add(name, attribute) 
     # Other stuff 
    end 
    end 
end 

class Stuff 
    include EncryptedFields 

    encrypted :ololo 
    encrypted :new_name 
end 

EncryptedFields.instance_variable_get(:@encrypted_attributes) 
=> {"Stuff"=>[:ololo, :new_name]} 

Вам не нужны переменный класс здесь. Момента экземпляра экземпляра будет достаточно. У вас нет наследования, и вы не можете создать экземпляр модуля, поэтому у вас всегда будет только одно место, где будет определена переменная @encripted_attributes, и это будет ваш модуль EncriptedFields.

Хорошая статья относительно разницы между переменным классом и экземпляром класса переменным: http://www.railstips.org/blog/archives/2006/11/18/class-and-instance-variables-in-ruby/

+0

Благодарности. Это был образовательный ответ. Я упростил свой код для вопроса, так что это может не сработать точно, но это заставило меня задуматься в новом направлении. – BoringJangles