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
4

2 に答える 2

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
于 2013-10-31T20:09:13.100 に答える
0

ステートマシンを探しているようです。

Ruby では、state_machineまたはaasm gem を確認してください。次に、列に基づいてスコープを定義できstateます (または、 is という名前を付けることができstatusます)。

ステート マシンはステータス間の遷移の管理にも役立つため、特定の遷移またはステータスでのみコールバックまたは検証を実行できます。

于 2013-10-31T20:10:32.113 に答える