【问题标题】:Rails Active Record AssociationsRails 活动记录关联
【发布时间】:2012-06-23 01:41:44
【问题描述】:

我一直在阅读和重新阅读 Rails 关联指南:

http://guides.rubyonrails.org/association_basics.html

这很接近,但不完全相同:

Ruby on rails active record associations

我不确定如何设置以下场景。

事件的状态为挂起、打开或关闭。

我认为这很简单,只需:

event has_one status
status belongs_to event

但这确实不是一对一的关系,因为一个状态可以属于许多事件。

所以我想我会做这样的事情:

status has_many events
event belongs_to status

但这看起来很有趣,因为状态不拥有事件。一个事件拥有一个状态,对吧?

我曾尝试使用枚举但没有状态模型。但这变得很棘手,因为 ActiveRecord 似乎并不真正支持枚举。我还认为,如果有人想要扩展状态选项的数量,例如添加“等待批准”或其他内容,那么拥有一个单独的模型可能会很好。

这篇文章表明我的后一种设置没问题,尽管它读起来很有趣:

Really easy Rails Active-Record Associations question

但我只是想知道我是否不知道有更好的 Ruby/Rails 方法来处理这个简单的场景。

提前致谢!

【问题讨论】:

    标签: ruby-on-rails associations has-many belongs-to has-one


    【解决方案1】:

    将其作为活动记录关联进行操作是过大的。想想看,创建一个完整的表只是为了在其中存储 3 个永远不会改变的值?

    你真正需要的是一个枚举。但当然,ruby 没有枚举。

    幸运的是,你可以伪造它。

    module StatusCodes
      pending = 0
      open = 1
      closed = 2
    end
    

    然后你可以做这样的事情

    if @event.status == StatusCodes::open
      # do something
    end
    

    这是一个更简单的解决方案,并且您的代码可读性很好。

    【讨论】:

    • 是的,我同意。感谢您提出这个替代方案!保重!
    【解决方案2】:

    忽略你脑海中的那个声音:你做得很好。哪个模型具有belongs_to 真正重要的是存储外键的位置。在这个例子中很清楚,外键应该存储在Event模型中,这意味着它应该是belongs_to :status

    不过,我也同意其他帖子 - 如果您有少量且固定数量的潜在 Status 记录,请考虑创建一个常量哈希来存储它们,而不是为它们创建整个数据库表。

    为什么不将status 列添加到Event(作为整数),并有这样的东西:

    class Event < ActiveRecord::Base
      STATUS_TYPES = {1 => "active", 2 => "inactive", 3 => "closed"}
    
      def status
        STATUS_TYPES[self[:status]]
      end
    
      def status=(new_status)
        new_status = STATUS_TYPES.invert[new_status] if new_status.class == "String"
        self[:status] = new_status
      end
    end
    

    【讨论】:

    • 感谢您的保证。这可能是我下次遇到这个问题时会做的事情。谢谢!
    【解决方案3】:

    您可能需要考虑使用state_machine 和一个简单的字符串列来实现状态,而不是使用关联或手动枚举。

    【讨论】:

    • 哇...状态机。很高兴知道。我会把这个放在我的后兜里。
    【解决方案4】:

    你错了。

    如果你这样做

    Event
     has_one :status
    
    Status
     belongs_to :event
    

    Rails 会确保它是一对一的关联,因此状态只会属于一个事件

    我很确定如果您尝试将事件状态分配给不同的事件会发生这种情况

    e1 = Event.first
    status = e1.status
    
    e2 = Event.new
    e2.status = status
    e2.save
    
    Event.first.status #=> nil
    

    【讨论】:

    • 是的,我同意你的看法。这就是为什么我正在考虑第二种选择,因为这个问题。但是第二个选项似乎是我在强迫 ActiveRecord 做一些它不打算做的事情。在指南中它这样说:“例如,说供应商拥有一个帐户比说一个帐户拥有一个供应商更有意义。”所以对于我的第二个选项,我会说“一个状态拥有一个事件”。这对我来说很有趣。也许我只是在想这个?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-10
    • 1970-01-01
    相关资源
    最近更新 更多