J'essaie de sauvegarder un identifiant de mappage de hachage pour un certain nombre de tentatives dans mon Rails. Ma migration vers la base de données pour répondre à cette nouvelle colonne:
class AddMultiWrongToUser < ActiveRecord::Migration
def self.up
add_column :users, :multi_wrong, :string
end
def self.down
remove_column :users, :multi_wrong
end
end
Dans mon modèle j'ai:
class User < ActiveRecord::Base
serialize :multi_wrong, Hash
end
Mais lorsque j’utilise la console Rails) pour tester cela, procédez comme suit:
user = User.create()
user.multi_wrong = {"test"=>"123"}
user.save
La sortie est fausse. Qu'est-ce qui ne va pas ici?
Le type de colonne est incorrect. Vous devriez utiliser Text au lieu de String. Par conséquent, votre migration devrait être:
def self.up
add_column :users, :multi_wrong, :text
end
Alors Rails le convertira correctement en YAML pour vous (et effectuera la sérialisation appropriée). Les champs de chaînes de caractères ont une taille limitée et ne contiendront que des valeurs particulièrement petites.
UPDATED:
L'implémentation exacte dépendra de votre base de données, mais PostgreSQL dispose maintenant des colonnes json
et jsonb
qui peuvent stocker de manière native vos données de hachage/objet et vous permettent de interroger le JSON avec ActiveRecord !
changez votre migration et vous avez terminé.
class Migration0001
def change
add_column :users, :location_data, :json, default: {}
end
end
ORIGINAL:
Pour plus de détails: documentation Rails && apidock
Assurez-vous que votre colonne est :text
et pas :string
Migration:
$ Rails g migration add_location_data_to_users location_data:text
devrait créer:
class Migration0001
def change
add_column :users, :location_data, :text
end
end
Votre classe ressemblerait à:
class User < ActiveRecord::Base
serialize :location_data
end
Actions disponibles:
b = User.new
b.location_data = [1,2,{foot: 3, bart: "noodles"}]
b.save
Plus génial?!
utiliser postgresql hstore
class AddHstore < ActiveRecord::Migration
def up
enable_extension :hstore
end
def down
disable_extension :hstore
end
end
class Migration0001
def change
add_column :users, :location_data, :hstore
end
end
Avec hstore, vous pouvez définir des attributs sur le champ sérialisé
class User < ActiveRecord::Base
# setup hstore
store_accessor :location_data, :city, :state
end
Rails 4 a une nouvelle fonctionnalité appelée Store , de sorte que vous pouvez facilement l'utiliser pour résoudre votre problème. Vous pouvez définir un accesseur pour celui-ci et il est recommandé de déclarer la colonne de base de données utilisée pour le magasin sérialisé sous forme de texte, afin de laisser beaucoup d'espace. L'exemple original:
class User < ActiveRecord::Base
store :settings, accessors: [ :color, :homepage ], coder: JSON
end
u = User.new(color: 'black', homepage: '37signals.com')
u.color # Accessor stored attribute
u.settings[:country] = 'Denmark' # Any attribute, even if not specified with an accessor
# There is no difference between strings and symbols for accessing custom attributes
u.settings[:country] # => 'Denmark'
u.settings['country'] # => 'Denmark'