2013-10-31 4 views
0

class << 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

상태 머신을 찾고있는 것으로 보입니다.

루비에서는 state_machine 또는 aasm 보석을 확인하십시오. 그런 다음 state 열을 기반으로 범위를 정의 할 수 있습니다 (또는 이름은 status입니다).

상태 시스템은 상태 간의 전환을 관리하는 데 도움이되므로 특정 전환이나 상태에서만 콜백 또는 유효성 검사를 실행할 수 있습니다.