【问题标题】:Sort by state in database按数据库中的状态排序
【发布时间】:2011-01-26 08:08:13
【问题描述】:

鉴于我有一个模型 house,它经历了几个状态,如下所示: Dreaming —> Planning —> Building —> Living —> Tearing down

如果我想从数据库中检索十所房屋并按状态字段对它们进行排序,我会首先获得Building 状态的所有房屋,然后是Dreaming,然后是Living,...

是否可以从数据库中获取所有房屋,并在检索它们之前按状态按照预期的顺序对它们进行排序?意思是,首先是Dreaming 状态的所有房屋,然后是Planning,等等。通过在数组中提供顺序以进行排序比较。

我希望在获取所有条目后避免在 Ruby 中执行此操作,并且我不想为状态使用 ID。

在阅读了枚举实现之后,我想,如果我能让它工作,我会尝试将enum column pluginstate_machine plugin 结合起来以实现我所追求的。如果有人以前做过这样的事情(尤其是 Rails 3 下的组合),我将不胜感激!

【问题讨论】:

    标签: ruby-on-rails ruby database sorting


    【解决方案1】:

    这里有一些关于如何在 rails 中使用 SQL ENUM 的信息——它们是相对可移植的数据库,大致可以满足你的需求——http://www.snowgiraffe.com/tech/311/enumeration-columns-with-rails/

    【讨论】:

    • 这看起来很有趣!非常感谢。我不得不承认我对枚举类型一无所知。快速查找发现:github.com/ikspres/enum_fu — 你碰巧有使用这些库的经验吗?排序真的按预期工作吗?
    • 我想我会采用混合方法并尝试使用 enum_column 插件。
    【解决方案2】:

    如果您使用的是 MySQL,那么解决方案是 ORDER BY FIELD(state, 'Building', 'Dreaming', 'Living', ...):

    House.order("FIELD(state, 'Building', 'Dreaming', 'Living', ...)")
    

    【讨论】:

    • 谢谢!没有独立于数据库的方式来使用此功能,是吗?
    • 好吧,你可以改用 case/when/else - 它在 MySQL 和 Postrgesql 中都可以工作 stackoverflow.com/questions/1309624/…
    【解决方案3】:

    如果您想在某个条件之后对集合进行排序,那么您必须将该条件存储在某处。

    我不知道这是否违反您的“不在 Ruby 中”标准,但我可能会这样做:

    class House < ActiveRecord::Base
      STATES { 0 => "Dreaming",
               1 => "Planning",
               2 => "Building",
               3 => "Living",
               4 => "Tearing Down" }
    
      validates_inclusion_of :state, :in => STATES.keys
    
      def state_name
        STATES[self.state]
      end
    end
    
    @houses = House.order("state")
    

    在这种情况下,db 字段状态是整数而不是字符串。它对于数据库存储和查询非常有效。

    然后在您看来,您调用 state_name 从存储在模型中的 STATES 哈希中获取正确的名称。这也可以通过使用标签而不是哈希中的字符串来更改为使用 i18n 本地化。

    【讨论】:

    • 感谢您的回答。不过,这就是我所说的字段 ID 的意思。为此,我希望能够将州名用作字符串。
    • 没问题。我只想问,为什么需要使用字符串?是否有其他应用程序使用相同的数据库?
    • 实际上这个字段可能会被某种状态机使用,我只是想让代码尽可能简单。在这种情况下,拥有这一抽象层肯定会对我有所帮助,但我感觉它会在其他情况下引入问题和可能的错误。 ——你怎么看?
    • 实际上,我认为我的解决方案非常适合状态机场景。像 def next_state;状态[self.state + 1];仅举一个例子。但如果你认为它会太复杂,那么你不应该这样做。
    • 据我了解, enum_column 插件是否符合您的建议,但掩盖了“ID”。所以 +1 并再次感谢,我想我可能会采用混合方法。
    猜你喜欢
    • 1970-01-01
    • 2018-04-20
    • 2015-05-14
    • 1970-01-01
    • 1970-01-01
    • 2015-10-19
    • 1970-01-01
    • 2021-09-30
    • 2016-08-30
    相关资源
    最近更新 更多