0

我一直在阅读和重新阅读 Rails 协会指南:

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

这很接近但不完全相同:

Ruby on Rails 活动记录关联

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

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

我认为这很简单,只需:

event has_one status
status belongs_to event

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

所以我想我会做类似的事情:

status has_many events
event belongs_to status

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

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

这篇文章表明我的后一种设置是可以的,即使它读起来很有趣:

非常简单的 Rails Active-Record 关联问题

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

提前致谢!

4

4 回答 4

3

这样做作为一个活动的记录关联是矫枉过正的。想想看,创建一个完整的表只是为了在其中存储 3 个永远不会改变的值?

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

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

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

然后你可以做这样的事情

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

这是一个更简单的解决方案,您的代码保持非常可读。

于 2012-06-23T02:29:42.657 回答
2

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

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

为什么不添加一statusEvent(作为整数),并有这样的东西:

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
于 2012-06-23T02:31:56.867 回答
1

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

于 2012-06-23T03:07:31.767 回答
0

你错了。

如果你这样做

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
于 2012-06-23T01:54:24.413 回答