हैश को डेटाबेस में सहेजने के लिए रेल का उपयोग क्रमबद्ध करें


135

मैं अपने रेल एप्लिकेशन में कई प्रयासों के लिए हैश मैपिंग आईडी को बचाने की कोशिश कर रहा हूं। डेटाबेस में मेरा माइग्रेशन इस नए कॉलम को समायोजित करने के लिए:

class AddMultiWrongToUser < ActiveRecord::Migration
  def self.up
    add_column :users, :multi_wrong, :string
  end

  def self.down
    remove_column :users, :multi_wrong
  end
end

मेरे मॉडल में मेरे पास है:

class User < ActiveRecord::Base 
 serialize :multi_wrong, Hash
end

लेकिन जब मैं ऐसा करके परीक्षण करने के लिए रेल कंसोल का उपयोग करता हूं:

user = User.create()
user.multi_wrong = {"test"=>"123"}
user.save

आउटपुट झूठा है। यहाँ क्या गलत हो रहा है?


4
क्या रिकॉर्ड को बचाने के प्रयास के बाद user.errors में कुछ है?
मार्टिज़न

1
भविष्य में, आप एक अपवाद बढ़ाने और त्रुटि संदेश प्रदर्शित करने के लिए बैंग विधि (सहेजें!) का उपयोग कर सकते हैं।
लीशमैन

सबसे अच्छा जवाब अब एक JSON कॉलम stackoverflow.com/a/21397522/1536309
ब्लेयर एंडरसन

जवाबों:


174

कॉलम का प्रकार गलत है। आपको स्ट्रिंग के बजाय टेक्स्ट का उपयोग करना चाहिए। इसलिए, आपका माइग्रेशन होना चाहिए:

 def self.up
   add_column :users, :multi_wrong, :text
 end

फिर रेल आपके लिए इसे ठीक से YAML में बदल देगा (और उचित क्रमांकन करेगा)। स्ट्रिंग्स फ़ील्ड आकार में सीमित हैं और केवल विशेष रूप से छोटे मूल्यों को धारण करेंगे।


1
@BenjaminTan इसके पीछे क्या कारण है, मैं हैश को 'स्ट्रिंग' डेटा प्रकार में संग्रहीत क्यों नहीं कर सकता।
लोहित एमवी

8
क्योंकि डेटाबेस में, स्ट्रिंग की निश्चित लंबाई 255 (मुझे लगता है) है। लेकिन यदि आप तुलनात्मक आकार के हैश को क्रमबद्ध करना चाहते हैं, तो यह आसानी से लंबाई को पार कर जाएगा। Arrays के लिए एक ही मामला। पाठ बहुत बड़ी लंबाई की अनुमति देता है।
बेंजामिन टैन वेई हाओ

72

अपडेट:

सटीक कार्यान्वयन आपके डेटाबेस पर निर्भर करेगा, लेकिन अब PostgreSQL के पास कॉलम jsonऔर jsonbकॉलम हैं जो आपके हैश / ऑब्जेक्ट डेटा को मूल रूप से स्टोर कर सकते हैं और आपको JSON के खिलाफ ActiveRecord के साथ क्वेरी करने की अनुमति दे सकते हैं !

अपना माइग्रेशन बदलें और आपका काम हो गया।

class Migration0001
  def change
    add_column :users, :location_data, :json, default: {}
  end
end

मूल:

अधिक जानकारी के लिए: डॉक्स और एपी एपिडॉक रेल

सुनिश्चित करें कि आपका कॉलम है :textऔर नहीं:string

माइग्रेशन:

$ rails g migration add_location_data_to_users location_data:text

बनाना चाहिए:

class Migration0001
  def change
    add_column :users, :location_data, :text
  end
end

आपका वर्ग कैसा दिखेगा:

class User < ActiveRecord::Base
  serialize :location_data
end

उपलब्ध कार्य:

b = User.new
b.location_data = [1,2,{foot: 3, bart: "noodles"}]
b.save

अधिक भयानक ?!

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

Hstore के साथ आप serialized फ़ील्ड पर विशेषताएँ सेट कर सकते हैं

class User < ActiveRecord::Base  
  # setup hstore
  store_accessor :location_data, :city, :state
end

2
सचमुच कमाल! धन्यवाद!
अलेक्जेंडर गोर्ग

18

रेल 4 में एक नई सुविधा है जिसे स्टोर कहा जाता है , ताकि आप अपनी समस्या को हल करने के लिए आसानी से इसका उपयोग कर सकें। आप इसके लिए एक एक्सेसर को परिभाषित कर सकते हैं और यह अनुशंसा की जाती है कि आप धारावाहिक स्टोर के लिए इस्तेमाल किए गए डेटाबेस कॉलम को एक पाठ के रूप में घोषित करें, इसलिए इसमें बहुत जगह है। मूल उदाहरण:

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'
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.