2013-10-31 29 views
0

如何從class << self上下文中動態指定示波器?從類內動態定義示波器<< self

class Partner < ActiveRecord::Base 

    STATUS = { 
    pending: 0, # 0 account has a pending billing request (but is not yet open) 
    active: 1,  # 1 account has an active base subscription 
    suspended: 2, # 2 account has been suspended (e.g. after a base subscription decline) 
    expired: 3, # 3 base subscription has expired 
    incomplete: 4, # 4 partner application process incomplete 
    closed: 5,  # 5 account has been permanently closed 
    cancelled: 6 # 6 account has been cancelled by user (but is still unexpired) 
    } 

    after_initialize :setup_status_enums 

    def status 
    STATUS.key(read_attribute(:status)) 
    end 

    def status=(s) 
    write_attribute(:status, STATUS[s]) 
    end 

    private 

    def setup_status_enums 
      class << self 
      STATUS.map do |key, val| 
       raise "Collision in enum values method #{key}" if respond_to?("#{key.to_s}?") or respond_to?("#{key.to_s}!") or respond_to?("#{key.to_s}") 

       define_method "#{key.to_s}?" do 
       send("status") == key 
       end 

       define_method "#{key.to_s}!" do 
       send("status=", val) 
       end 

       scope key.to_sym, lambda { where(:status => val) } 
      end 
      end 
    end 

end 

回答

0

像這樣的東西應該工作。你可以在你的類定義中迭代你的STATUS散列。

class Partner < ActiveRecord::Base 
    STATUS = { 
    pending: 0, # 0 account has a pending billing request (but is not yet open) 
    active: 1,  # 1 account has an active base subscription 
    suspended: 2, # 2 account has been suspended (e.g. after a base subscription decline) 
    expired: 3, # 3 base subscription has expired 
    incomplete: 4, # 4 partner application process incomplete 
    closed: 5,  # 5 account has been permanently closed 
    cancelled: 6 # 6 account has been cancelled by user (but is still unexpired) 
    } 

    STATUS.each do |key, val| 
    define_method "#{key.to_s}?" do 
     status == key 
    end 

    define_method "#{key.to_s}!" do 
     status = val 
    end 

    scope key, lambda { where(status: val) } 
    end 

    ... 
end 
0

看來你正在尋找一個狀態機。

在Ruby中,查看state_machineaasm寶石。然後,您可以基於state列(或者您可以命名爲status)來定義示波器。

狀態機還將幫助您管理狀態之間的轉換,因此您只能針對特定轉換或狀態運行回調或驗證。

相關問題