簡體   English   中英

在Ruby中增加枚舉?

[英]Incrementing enums in Ruby?

假設我在模型中有enum stage [:one, :two, :three, :four]

當調用控制器動作next_stage (用戶單擊按鈕以將其發送到下一個階段)時,我想從X階段逐步轉到Y階段。最簡單的方法是什么? 我目前使用的是重大案件,但我覺得我可以做得更好。 我將提供用例:

Class MyController
  def next_stage
    # @my_controller.stage => "two"
    @my_controller.stage.value++ unless @my_controller.stage.four?
    # @my_controller.stage => "three"
  end
end

老實說,如果您要存儲以特定順序移動的狀態,則應使用狀態機。 https://github.com/aasm/aasm支持使用枚舉存儲狀態。 你可以做這樣的事情;

aasm :column => :stage, :enum => true do
  state :stage1, :initial => true
  state :stage2
  state :stage3
  state :stage4

  event :increment_stage do
    transitions from: :stage1, to: :stage2
    transitions from: :stage2, to: :stage3
    transitions from: :stage3, to: :stage4
  end
end

它不僅可以清理您的邏輯,而且測試會更簡單,並且您可以對不同事件進行各種回調。 這對於任何類型的工作流程也都非常好(例如,將帖子從審核轉移到批准等)

編輯:我還可以建議,如果您不想使用狀態機,那么至少要將此狀態轉移邏輯移入模型中? 控制器與訪問控制有關,模型與狀態有關。

model.read_attribute('foo') ,但是從我發現的枚舉中獲取整數的唯一方法是執行model.read_attribute('foo')因此,您可以嘗試執行

def next_stage
  @my_controller.update_column(:stage, @my_controller.read_attribute('stage')+1) unless @my_controller.four?
end

您的代碼似乎有點奇怪, @my_controller@my_controller 什么是stage

除此之外,如果我理解正確,那么您想要的是:

@my_controller[:stage] += 1 unless @my_controller.four?

枚舉以整數形式存儲在數據庫中,它們從0開始,以1為增量。因此,只需訪問原始屬性數據並將其遞增即可。

有一個gem simple_enum ,可以使用更強大的枚舉。

枚舉將允許您同時使用整數和/或符號,然后您可以執行以下操作

@my_controller.stage.value_cd += 1 unless @my_controller.stage.last_stage?

您可以將其與ActiveRecord / Mongoid一起使用,也可以與其他任何對象一起使用。

對於像Mongoid這樣的ORM,您的模型可能如下所示

class Project
  as_enum :status, {
        idea: 0, 
        need_estimate: 1,
        in_progress: 2,
        finished: 3,
        paid: 4,
        field: { type: Integer, default: 0 }

  def next_step!
    self.status_cd += 1 unless self.paid?
  end
end

project = Project.new
project.status # => :idea
project.need_estimate? #=> false
project.next_step!
project.need_estimate? #=> true

我不知道我是否正確。 也許您可以嘗試以下方法:

    Class MyController
      def next_stage
        @my_controller.stage.increment! :value rescue nil
      end
    end

新答案

好的,我想我會更好地了解您的需求。 這個怎么樣:

在模型中,使用哈希而不是數組設置Enum:

class MyClass < ActiveRecord::Base
  enum stage: {one: 1, two: 2, three: 3, four: 4} #just makes more sense when talking about stages
end

然后,您可以使用當前狀態的索引:

Class MyController
  def next_stage
    # @my_controller.stage => "two"
    current_stage = MyClass.stages[@my_controller.stage] # returns => 1
    current_stage += 1 unless current_stage == 4   # returns => 2
    @my_controller.update! stage: current_stage 
    # @my_controller.stage => "three"
  end
end

如果我正確理解了文檔,這也可能會起作用:

Class MyController
  def next_stage
    # @my_controller.stage => "two"
    @my_controller.update! stage: MyClass.stages[@my_controller.stage] + 1 unless @my_controller.stage == :four 
    # @my_controller.stage => "three"
  end
end

這是袖手旁觀,可能可以通過某些方式進行清理。 我不能做太多實驗,因為我沒有在Rails應用程序中進行任何設置,而帶有枚舉。

舊的答案留給存檔。

def next_stage
  self.next
end

編輯我看到枚舉,並認為您正在將可枚舉縮短為枚舉(如x.to_enum )。 不太確定這在某種程度上對您不起作用。 您要求的不是丑陋的陳述。 您可以使用從該列獲取當前枚舉數的枚舉數來設置起點,終點為4(或:4,具體取決於編寫方式),並在枚舉數末尾進行救援以返回最大值。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM