ما هي أفضل طريقة للتعامل مع الثوابت في روبي عند استخدام القضبان؟
-
06-07-2019 - |
سؤال
ولدي بعض الثوابت التي تمثل الخيارات الصالحة في أحد حقول بلدي النموذج. ما هي أفضل طريقة للتعامل مع هذه الثوابت في روبي؟
المحلول
ويمكنك استخدام صفيف أو التجزئة لهذا الغرض (في environment.rb الخاص بك):
OPTIONS = ['one', 'two', 'three']
OPTIONS = {:one => 1, :two => 2, :three => 3}
وأو بدلا من فئة تعداد، والذي يسمح لك لتعداد على الثوابت الخاصة بك وكذلك تستخدم مفاتيح ربط لهم:
class Enumeration
def Enumeration.add_item(key,value)
@hash ||= {}
@hash[key]=value
end
def Enumeration.const_missing(key)
@hash[key]
end
def Enumeration.each
@hash.each {|key,value| yield(key,value)}
end
def Enumeration.values
@hash.values || []
end
def Enumeration.keys
@hash.keys || []
end
def Enumeration.[](key)
@hash[key]
end
end
والتي يمكنك بعد ذلك تنبع من:
class Values < Enumeration
self.add_item(:RED, '#f00')
self.add_item(:GREEN, '#0f0')
self.add_item(:BLUE, '#00f')
end
وواستخدام مثل هذا:
Values::RED => '#f00'
Values::GREEN => '#0f0'
Values::BLUE => '#00f'
Values.keys => [:RED, :GREEN, :BLUE]
Values.values => ['#f00', '#0f0', '#00f']
نصائح أخرى
وأنا وضعها مباشرة في فئة النموذج، كما يلي:
class MyClass < ActiveRecord::Base
ACTIVE_STATUS = "active"
INACTIVE_STATUS = "inactive"
PENDING_STATUS = "pending"
end
وبعد ذلك، عند استخدام نموذج من فئة أخرى، والرجوع إلى الثوابت
@model.status = MyClass::ACTIVE_STATUS
@model.save
إذا أنها هي التي تقود سلوك النموذج، ثم الثوابت يجب أن تكون جزءا من نموذج:
class Model < ActiveRecord::Base
ONE = 1
TWO = 2
validates_inclusion_of :value, :in => [ONE, TWO]
end
وهذا سوف يسمح لك لاستخدام القضبان وظيفة المدمج في:
>> m=Model.new
=> #<Model id: nil, value: nil, created_at: nil, updated_at: nil>
>> m.valid?
=> false
>> m.value = 1
=> 1
>> m.valid?
=> true
وبدلا من ذلك، إذا كانت قاعدة البيانات تدعم التعدادات، ثم يمكنك استخدام شيء من هذا القبيل في التعداد العمود المساعد.
والقضبان 4،1 أضاف دعم تتضمن التعدادات أكتيفيريكورد .
وتعلن سمة التعداد حيث خريطة القيم إلى أعداد صحيحة في قاعدة البيانات، ولكن يمكن الاستعلام بالاسم.
class Conversation < ActiveRecord::Base
enum status: [ :active, :archived ]
end
conversation.archived!
conversation.active? # => false
conversation.status # => "archived"
Conversation.archived # => Relation for all archived Conversations
ثائقها للحصول على كتابة ما يصل تفصيلا.
ويمكنك أيضا استخدامه داخل النموذج الخاص بك داخل تجزئة مثل هذا:
class MyModel
SOME_ATTR_OPTIONS = {
:first_option => 1,
:second_option => 2,
:third_option => 3
}
end
واستخدامها مثل هذا:
if x == MyModel::SOME_ATTR_OPTIONS[:first_option]
do this
end
ويمكنك أيضا ثوابت المجموعة إلى الموضوعات، باستخدام وحدة -
class Runner < ApplicationRecord
module RUN_TYPES
SYNC = 0
ASYNC = 1
end
end
ويكون ذلك الحين،
> Runner::RUN_TYPES::SYNC
=> 0
> Runner::RUN_TYPES::ASYNC
=> 1