यदि कोई प्लगइन या ActiveRecord क्लास स्थापित करने का सबसे अच्छा तरीका है तो आश्चर्य की बात है, उदाहरण के लिए, जब कोई रिकॉर्ड "प्रकाशित" स्थिति दर्ज करता है, तो कुछ विशेषताओं को जमे हुए होते हैं कि वे छेड़छाड़ नहीं किया जा सका।Rails ActiveRecord: रिकॉर्ड किसी विशेष स्थिति में प्रवेश करते समय गुणों को लॉक करना
उत्तर
आप @readonly को सही (विधि में) सेट करके एक संपूर्ण AR :: B ऑब्जेक्ट को फ्रीज कर सकते हैं, लेकिन यह सभी विशेषताओं को लॉक कर देगा।
तरह से मैं सिफारिश करेंगे विशेषता सेटर तरीकों कि सुपर को पार करने से पहले वर्तमान स्थिति के लिए जाँच को परिभाषित करते हुए है:
class Post < ActiveRecord::Base
def author=(author)
super unless self.published?
end
def content=(content)
super unless self.published?
end
end
[संपादित करें] या विशेषताओं की एक बड़ी राशि के लिए:
class Post < ActiveRecord::Base
%w(author content comments others).each do |method|
class_eval <<-"end_eval", binding, __FILE__, __LINE__
def #{method}=(val)
super unless self.published?
end
end_eval
end
end
मैं निश्चित रूप से दूसरों के साथ साझा करने के लिए एक प्लगइन में खींचने की वकालत करता हूं, और disable_attributes :author, :content, :comments, :when => :published?
आप एसी जोड़ सकते हैं यदि आप किसी निश्चित स्थिति में हैं तो गुणों में परिवर्तनों को अवरुद्ध करने के लिए कस्टम सत्यापन। आप सीधे कोड प्रमाणीकरण में हार्ड कोड चीजें कर सकते हैं। लेकिन मैं एक श्वेतसूची (एक राज्य में बदलने की अनुमति देने वाले गुणों की सूची) या एक ब्लैकलिस्ट परिभाषित करने वाले स्थिरांक का उपयोग करके थोड़ा अधिक मजबूत दृष्टिकोण पसंद करता हूं (गुणों की सूची किसी राज्य में बदलने की अनुमति नहीं है)।
यहां दोनों दृष्टिकोणों का एक उदाहरण दिया गया है। प्रत्येक दृष्टिकोण मानता है कि आपके मॉडल में एक राज्य विधि है जो वर्तमान/नए राज्य को स्ट्रिंग के रूप में लौटाती है।
श्वेत सूची दृष्टिकोण
WhiteListStateLockMap = {
"state_1" => [
"first_attribute_allowed_to_change_in_state_1",
"second_attribute_allowed_to_change_in_state_1",
...
],
"state_2" => [
"first_attribute_allowed_to_change_in_state_2",
"second_attribute_allowed_to_change_in_state_2",
...
],
...
}
validates :state_lock
def state_lock
# ensure that all changed elements are on the white list for this state.
unless changed & WhiteListStateLockMap[state] == changed
# add an error for each changed attribute absent from the white list for this state.
(changed - WhiteListStateLockMap[state]).each do |attr|
errors.add attr, "Locked while #{state}"
end
end
end
काला सूची दृष्टिकोण
BlackListStateLockMap = {
"state_1" => [
"first_attribute_not_allowed_to_change_in_state_1,
"second_attribute_not_allowed_to_change_in_state_1,
...
],
"state_2" => [
"first_attribute_not_allowed_to_change_in_state_2",
"second_attribute_not_allowed_to_change_in_state_2",
...
],
...
}
validates :state_lock
def state_lock
# ensure that no changed attributes are on the black list for this state.
unless (changed & BlackListStateLockMap[state]).empty?
# add an error for all changed attributes on the black list for this state.
(BlackListStateLockMap[state] & changed).each do |attr|
errors.add attr, "Locked while #{state}"
end
end
end
पोस्ट करने के बाद, मुझे एहसास हुआ कि मेरा समाधान अनिवार्य रूप से लिखे गए सिवाय इसके अलावा, इस तरह के समान था। मेरा मानना है कि मेरा अधिक स्पष्ट है, लेकिन यह भी अच्छा है, क्योंकि यह अधिक घोषणात्मक है। –
एम्फी - प्रतिक्रिया के लिए धन्यवाद।यह मेरे रूबी ज्ञान के लिए थोड़ा उन्नत है, एक सिंगल एम्परसैंड से जुड़ी दो लाइनों की रेखाओं के संदर्भ में, यह सुनिश्चित नहीं है कि वास्तव में क्या हो रहा है, जब तक कि यह एक और नहीं है - मुझे वास्तव में इसका परीक्षण करने में त्रुटि हो रही है: अपरिभाषित विधि ' और 'के लिए {}: हैश –
और सरणी के लिए चौराहे ऑपरेटर है। http://ruby-doc.org/core/classes/Array.html#M002212। ऐरे ए और ऐरे बी तत्वों को दोनों सरणी के लिए आम तौर पर लौटाता है। यदि ए और बी == ए तो ए के सभी तत्व बी में हैं। इसके अलावा आपको मेरी एक टाइपो की वजह से त्रुटि मिल रही है जिसकी प्रतिलिपि बनाई गई है और कई बार चिपकाया गया है। परिवर्तनों के सभी उदाहरण बदल गए होंगे। मैंने इस – EmFi
विशेषताएं संपादित करना जो संपादित नहीं किया जाना चाहिए एक प्रमाणीकरण त्रुटि है:
class Post < ActiveRecord::Base
validate :lock_down_attributes_when_published
private
def lock_down_attributes_when_published
return unless published?
message = "must not change when published"
errors.add(:title, message) if title_changed?
errors.add(:published_at, message) if published_at_changed?
end
end
थी एस 2.212 में पेश किए गए ActiveRecord::Dirty एक्सटेंशन का उपयोग करता है।
को प्रतिबिंबित करने के लिए समाधान अद्यतन किया है फ्रैंकोइस प्रतिक्रिया के लिए धन्यवाद, यह ऐसा करने का एक और शानदार तरीका है। –
यदि विशेष स्थिति केवल persisted?
है, तो attr_readonly
सबसे अच्छा विकल्प है।
attr_readonly
(*attributes)
सार्वजनिक
Attributes listed as readonly will be used to create a new record but update operations will ignore these fields.
परीक्षण करने के लिए (THAiSi के सौजन्य से):
class MyModel < ActiveRecord::Base
attr_readonly :important_type_thingie
end
#RSpec
describe MyModel do
its('class.readonly_attributes') { should include "important_type_thingie" }
it "should not update the thingie" do
m = create :my_model, :important_type_thingie => 'foo'
m.update_attributes :important_type_thingie => 'bar'
m.reload.important_type_thingie.should eql 'foo'
end
end
- 1. ActiveRecord/Rails
- 2. Rails में ActiveRecord में एकाधिक योग() s
- 3. मैं Rails/ActiveRecord
- 4. एनएसएलॉक - लॉक लॉक लॉक करते समय बस ब्लॉक करना चाहिए?
- 5. ActiveRecord/Rails को वास्तविक mysql TIMESTAMP कॉलम
- 6. Rails में ActiveRecord :: Base.connection.execute से त्रुटियों को कैप्चर कैसे करें?
- 7. Rails ActiveRecord क्वेरी पर रूबी
- 8. लगातार डब्लूसीएफ क्लाइंट को ग़लत स्थिति में प्रवेश करना
- 9. किसी विशेष समय
- 10. स्टोर और तुलना कैसे करें: ActiveRecord (Rails पर रूबी) में प्रतीकों
- 11. गुणों में लॉक, अच्छा दृष्टिकोण?
- 12. ActiveRecord: संबद्ध रिकॉर्ड को हटाने
- 13. AngularJS + Rails - संपत्तियों को संपीड़ित करते समय समस्याएं
- 14. किसी विशिष्ट उपयोगकर्ता को फ़ाइल में प्रवेश अनुमति प्रदान करना
- 15. सी # में किसी विशेष स्थिति पर डेटा कैसे लिखें?
- 16. रेलिंग में ActiveRecord प्रश्नों को फ़िल्टर करना
- 17. एसटीआई का उपयोग करते समय ActiveRecord ऑब्जेक्ट को किसी अन्य वर्ग में कैसे डाला जाए?
- 18. ActiveRecord/Rails मॉडल गुणों तक पहुंचने के लिए "स्वयं" का उपयोग क्यों करें?
- 19. आईओएस: पृष्ठभूमि में प्रवेश करते समय एक कार्य को खत्म करना
- 20. Rails ActiveRecord व्यवहार को नष्ट करने का सबसे अच्छा तरीका क्या है?
- 21. सी ++ किसी विशेष स्थिति में फ़ाइल में ओवरराइटिंग डेटा
- 22. क्या ActiveRecord (Rails) में create_view की तरह कुछ भी है?
- 23. रेल में xml प्रतिपादन से कुछ ActiveRecord गुणों को छोड़कर
- 24. सनस्पॉट में किसी विशेष मॉडल को रेइन्डेक्स करने में
- 25. कोडनिर्देशक: $ query-> free_result() सक्रिय रिकॉर्ड का उपयोग करते समय?
- 26. इकाई ढांचे का उपयोग करते समय संपादन के लिए रिकॉर्ड लॉक करने का सर्वोत्तम अभ्यास
- 27. किसी टेक्स्ट व्यू को किसी विशेष पंक्ति पर स्क्रॉल करना
- 28. पृष्ठभूमि में प्रवेश करते समय MPMoviePlayerViewController काला हो जाता है
- 29. बल में एक शाखा को लॉक करना?
- 30. वाईएक्स में, कस्टम क्रियाओं को निष्पादित करते समय स्थिति टेक्स्ट को अपडेट करना संभव है?
प्रतिक्रिया कॉलिन के लिए धन्यवाद। बड़ी संख्या में गुणों के लिए मुझे लगता है कि मैं लॉक होने की आवश्यकता वाले गुणों की एक सरणी में गुजरकर इन सेटर्स को ओवरराइट करने के लिए कक्षा उत्तीर्ण कर सकता हूं, आह? –
सटीक रूप से। मैंने बहस की कि क्या मुझे इसे कक्षा_वृत्त के रूप में लिखना चाहिए, लेकिन इसके खिलाफ पठनीयता के लिए फैसला किया। हालांकि मैं दूसरों के लिए इसका सामना करूंगा। –