متغيرات الفئة وإدراج الوحدة النمطية ، وتحديدا في ActionController
-
24-09-2019 - |
سؤال
أرغب في الحصول على نوع من القائمة الفردية التي يتم تهيئتها في وحدة نمطية منفصلة ، ثم يمكن تضمينها في وحدة تحكم وتعديلها على مستوى وحدة التحكم ، والوصول إليها على مستوى وحدة التحكم. اعتقدت أن متغيرات الفصل ستعمل هنا ، ولكن هناك شيء غريب يحدث ، لا يبدو أنها تتم تهيئتها في صف النهاية.
اكثر تحديدا:
لدي العديد من وحدات التحكم جميعها بما في ذلك بعض الوظائف الافتراضية ، في وحدة نمطية.
class BlahController < ApplicationController
include DefaultFunctionality
end
class FooController < ApplicationController
include DefaultFunctionality
end
module DefaultFunctionality
def show
render 'shared/show'
end
def model
controller_name
end
end
, ، على سبيل المثال. هذا ليس الرمز الفعلي ، ولكن هذا هو أكثر التفاعل الذي تتمتع به في الوقت الحالي.
أرغب في توسيع هذا الأمر مع بعض الوظائف الأخرى (واجهة قابلة للفرز للقوائم ،) مثل ذلك [لاحظ أنني أود أن أتمكن من تبديل وظائف قائمة الترتيب على أساس الفصل الدراسي]:
module DefaultFunctionality
module Sortable
def sort_params
params.slice(:order, :sort_direction).reverse_merge(default_sort_params)
end
def default_sort_params
@@sorts.first
end
def set_sorts(sorts = []) #sorts = [{:order => "most_recent", :sort_direction => :desc},...]
@@sorts = sorts
end
end
include Sortable
set_sorts([{:order => :alphabetical, :sort_direction => :asc}] #never run?
end
الفكرة هي التأكد من أنني قادر على تبديل مجموعة من جميع الأنواع الممكنة على أساس الفصل الدراسي ، مثل ذلك:
class FooController < ApplicationController
include DefaultFunctionality #calls the default set_sorts
set_sorts([{:order => :most_recent, :sort_direction => :asc}])
end
وأيضًا لصنع روابط لطيفة في طرق العرض ، كما هو موضح أدناه ، باستثناء أنني أتلقى خطأً.
___/blah/1 => shared/show.html.erb__
<%= link_to("upside down", polymorphic_path(model, sort_params) %><%#BOOOM uninitialized class variable @@sorts for BlahController %>
أعتقد أن class_var مكالمة سيئة ، لكن لا يمكنني التفكير فيما قد أستخدمه. (مثيل فئة var؟)
المحلول 3
انتهى بي الأمر باستخدام متغير مثيل مستوى الفصل الدراسي وإدراجه () مع عدم وجود أجهزة فرعية تلقائية ، قبل أن تلاحظ أن @tadman قد استجاب.
انتهى الأمر يبدو هكذا:
class BlahController < ApplicationController
include DefaultControllerFunctionality
include DefaultControllerFunctionality::Sortable
end
class FooController < ApplicationController
include DefaultControllerFunctionality
include DefaultControllerFunctionality::Sortable
sorts=([{:order => :most_recent, :sort_direction => :desc}])
end
في وحدات التحكم ، وتحت /lib
lib/default_controller_functionality.rb
module DefaultFunctionality
def show
render 'shared/show'
end
def model
controller_name
end
end
lib/default_controller_functionality/sortable.rb
module DefaultControllerFunctionality
module Sortable
def self.included(base)
base.helper_method :sort_params
base.class_eval <<-END
@sorts=[]
class << self; attr_accessor :sorts end
END
#this line ^ makes it so that the module
#doesn't work when included in any other
#module than the class you want @sorts to end up in.
#So don't include(Sortable) in DefaultControllerFunctionality and expect .sorts to work in FooController.
base.sorts= [{:order => :alphabetical, :sort_direction => :asc}]
end
def sort_params
params.slice(:order, :sort_direction).reverse_merge(default_sort_params)
end
def default_sort_params
self.class.sorts.first
end
end
end
نصائح أخرى
فئة مثيل VARS هي الطريق للذهاب ، بالتأكيد. نادراً ما تحتاج فعليًا إلى استخدام متغير فئة.
في إجابة محددة لمشكلتك ، ضع في اعتبارك أن أي رمز محدد في الوحدة النمطية الخاصة بك يتم تنفيذه مرة واحدة فقط عندما يتم تحميل الوحدة النمطية ليس عندما يتم تضمين الوحدة النمطية. قد لا يكون هذا التمييز واضحًا ، خاصةً عندما ينظر الناس "في أن" يشمل "أن يكون" يتطلب ".
ما تحتاجه هو:
module DefaultFunctionality
def sort_params
params.slice(:order, :sort_direction).reverse_merge(default_sort_params)
end
def default_sort_params
@sorts.first
end
def sorts=(sorts = nil)
@sorts = sorts || [{:order => "most_recent", :sort_direction => :desc}]
end
def self.included(base_class)
self.sorts = ([{:order => :alphabetical, :sort_direction => :asc}]
end
end
الطريقة التي تصطاد بها فئة بما في ذلك الوحدة النمطية الخاصة بك هي تحديد الوحدة النمطية. في هذه الحالة ، يتم استدعاء set_sorts في كل مرة يتم فيها تضمين هذه الوحدة ، وهي في سياق فئة الاتصال.
لقد قمت بتعديل هذا قليلاً لتضمين بعض التغييرات في النمط المحددة:
- إعلان الإعدادات الافتراضية الخاصة بك داخل الطريقة بدلاً من الإعلان. يتجنب إنتاج خطوط طويلة بشكل غير مقروء ، أو الاضطرار إلى هياكل البيانات المعقدة على خلاف ذلك.
- استخدام متغيرات مثيل الفئة التي ستقوم بالمهمة في هذه الحالة.
- باستخدام طريقة var = mutator على طراز Ruby بدلاً من set_var ()
عليك إضافة أ included
طريقة إلى الوحدة النمطية لهذا العمل.
module DefaultFunctionality
def self.included(base)
base.include(Sortable)
set_sorts([{:order => :alphabetical, :sort_direction => :asc}] #never run?
end
module Sortable
# other methods
def set_sorts(sorts = [{:order => "most_recent", :sort_direction => :desc}])
@@sorts = sorts
end
end
end