增加Ruby中的枚举?

时间:2015-07-17 20:05:32

标签: ruby-on-rails 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

6 个答案:

答案 0 :(得分:4)

老实说,如果你试图存储按特定顺序移动的状态,你应该使用状态机。 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

它不仅可以清理你的逻辑,而且测试会更简单,你可以对不同的事件进行各种回调。它对任何类型的工作流程都非常有用(比如将帖子从评论转移到批准等)。

编辑:我是否还可以建议,如果您不想使用状态机,那么您至少将此状态转换逻辑移动到您的模型中?控制器是关于访问控制的,模型是关于状态的。

答案 1 :(得分:3)

一种hackish,但是从我发现的enum中获取整数的唯一方法就是这样做 def next_stage @my_controller.update_column(:stage, @my_controller.read_attribute('stage')+1) unless @my_controller.four? end 所以你可以尝试做

$id             =   $_GET['song_id'];
$query          =   "SELECT * FROM store WHERE id = '$id'";
$result         =   mysql_query($query);
$row            =   mysql_fetch_array($result);
$strSQL         =   "Select hits from store WHERE id = '$id'";
$htop_tabelle   =   mysql_fetch_object(mysql_query($strSQL));
$hits           =   $htop_tabelle->hits;
$hits++;
$insertSQL      =   "UPDATE store SET hits = $hits WHERE id = '$id'";
$htop_tabelle   =   mysql_query($insertSQL);

mysql_close() or die ("Nicht getrennt");

答案 2 :(得分:0)

您的代码有点奇怪,@my_controller是什么?什么是stage

除此之外,如果我理解正确,你想要的是:

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

枚举作为整数存储在数据库中,它们从0开始,增量为1.因此,只需访问原始属性数据并递增它。

答案 3 :(得分:0)

有一个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

答案 4 :(得分:0)

我不知道自己是否做对了。也许你可以试试这个:

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

答案 5 :(得分:-1)

新答案

好的,我想我更了解你在寻找什么。怎么样:

在你的模型中使用哈希而不是数组设置你的枚举:

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

然后您可以使用当前状态'index:

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

编辑我看到了枚举,并认为你缩短了enum的枚举(如x.to_enum中所述)。不太确定这不会以某种形式对你有用。你问了一个丑陋的案例陈述以外的东西。您可以使用一个枚举器,该枚举器从该列获取当前枚举以设置起点,终点为4(或者:四取决于您的编写方式)并在枚举器末尾进行救援返回最大值。