متغيرات الفئة وإدراج الوحدة النمطية ، وتحديدا في ActionController

StackOverflow https://stackoverflow.com/questions/2374522

سؤال

أرغب في الحصول على نوع من القائمة الفردية التي يتم تهيئتها في وحدة نمطية منفصلة ، ثم يمكن تضمينها في وحدة تحكم وتعديلها على مستوى وحدة التحكم ، والوصول إليها على مستوى وحدة التحكم. اعتقدت أن متغيرات الفصل ستعمل هنا ، ولكن هناك شيء غريب يحدث ، لا يبدو أنها تتم تهيئتها في صف النهاية.

اكثر تحديدا:

لدي العديد من وحدات التحكم جميعها بما في ذلك بعض الوظائف الافتراضية ، في وحدة نمطية.

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
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top