2009-09-20 7 views
0

Je veux créer un ensemble de valeurs dans Ruby que je peux stocker et récupérer dans une base de données MySQL sous Rails.Stocker un tableau ou un hachage de booléens dans Ruby and Rails

Dans Delphi j'utiliser:

//Create an enumeration with four possible values 
type TColour = (clRed, clBue, clBlack, clWhite); 
//Create a set which can hold values from the above enumeration 
    TColours = set of TColours; 
//Create a variable to hold the set 
var MyColours = TColours; 
begin 
    //Set the variable to hold two values from the enumeration 
    MyColours = [clRed, clBlack]; 
    //MyColours now contains clRed and clBlack, but not clBlue or clWhite 

    //Use a typecast to convert MyColours to an integer and store it in the database 
    StoreInDatabase(Integer(MyColours)); 

    //Typecast the Integer back to a set to retrieve it from the database 
    MyColours := TColours(RetrieveFromDatabase); 
end; 

Je peux alors utiliser un transtypage pour convertir en/à partir d'un nombre entier.

Comment pourrais-je atteindre la même chose dans Ruby/Rails? Pour clarifier, supposons que j'avais un formulaire avec des cases à cocher pour 'Rouge', 'Bleu', 'Noir', 'Blanc'. L'utilisateur peut choisir aucune, une ou plusieurs valeurs. Comment stocker et récupérer cet ensemble de valeurs?

BTW, une autre façon de le faire en delphi est avec les mathématiques au niveau du bit:

const 
    Red = 1; 
    Blue = 2; 
    Black = 4; 
    White = 8; 
var MyColours: Integer; 
begin 
    MyColours := Red+Black; //(or MyColours = Red or Black) 

qui peut être stocké et récupéré sous forme d'entier

+0

Je préférerais que vous ajoutiez des commentaires à votre code pour élaborer ce que l'extrait précédent fait exactement. – khelll

Répondre

3

Voici une implémentation simple pour la solution de bitwise:

module Colors 
    Red = 1 
    Blue = 2 
    Black = 4 
    White = 8 
    ColorsSet = [Red,Blue,Black,White] 

    # Mixing valid colors 
    def self.mix(*colors) 
    colors.inject{|sum,color| ColorsSet.include?(color) ? color | sum : sum } 
    end 

    # Get an array of elements forming a mix 
    def self.elements(mix) 
    ColorsSet.select{|color| color & mix > 0} 
    end 
end 

mix = Colors::mix(Colors::Red,Colors::Blue) 

puts mix #=> 3 

puts Colors::elements(mix) 
#=> 1 
# 2 
+0

Merci. J'espérais que Ruby aurait une solution propre, prête à rouler, mais qui se révèle assez simple et efficace. –

1

Sur la base des commentaires et questions de révision, des sons comme vous voulez essayer sur le Enum Column plugin for Rails. A un assistant, enum_radio(), qui serait probablement utile dans votre forme.

+0

Je pense qu'il veut dire utiliser Enum. – Swanand

+0

Oui, Enum, quoi que l'on puisse croire, c'est dans la bonne direction. Mais ce dont j'ai besoin, c'est d'un champ qui peut stocker zéro ou plusieurs valeurs d'une énumération, comme une ligne de cases à cocher où aucun, un, ou plus d'un sont vérifiés. –

+0

Bon point. Bien que, Ruby n'a pas vraiment un type enum (peut le bidouiller je devine avec un module et des constantes). Je suppose que je ne faisais que masquer le "Je veux créer un ensemble de valeurs dans Ruby que je peux stocker et récupérer dans une base de données MySQL sous Rails." – rnicholson

0

Peut-être que vous trouvez cela plus facile

Colors={:red=>1, :blue=>2, :black=>4, :white=>8} 
mix = Colors[:blue] + Colors[:black] 
Colors.select{|key,value| value & mix > 0} 
=> [[:blue, 2], [:black, 4]]