如何比较Rails枚举类型

时间:2014-12-29 12:27:02

标签: ruby-on-rails ruby enums

我的Rails(4)应用程序中有以下枚举模型:

class Dual < ActiveRecord::Base
  enum dual: [:dual, :not_dual]

  validates :dual, uniqueness: true
  validates :dual, presence: true
end

我有另一个模型有很多Duals

class SillColour < ActiveRecord::Base
  has_many :sill_colour_duals, dependent: :destroy
  has_many :duals, through: :sill_colour_duals
end

我希望能够测试SillColour的实例是否有Dual枚举。这就是我可以开始工作的所有内容:

dual = Dual.find(1)
not_dual = Dual.find(2)

sill_colour.duals.include?(dual)
sill_colour.duals.include?(not_dual)

显然这是非常不可靠的,因为Duals的ID可以是生产中的任何东西(用于测试ID是固定的)。我试过这个:

dual = Dual.where(dual: 0)
not_dual = Dual.where(dual: 1)

甚至给出数据库duals表看起来像这样:

 id | dual 
----+------
  1 |    0
  2 |    1

我的测试失败,似乎是因为dualnon_dual不再正确比较。我用撬检查了它们,它们看起来和以前一样,但显然它们不是。

当然必须有更好的方法吗?我设想能够做到这一点:

sill_colour.duals.include?(Dual.dual)
sill_colour.duals.include?(Dual.not_dual)

但这也不起作用。

有什么建议吗?

1 个答案:

答案 0 :(得分:0)

我会尝试使用我的应用中的代码回答

class User < ActiveRecord::Base
  has_many :contacts
end

class Contact < ActiveRecord::Base
  enum status: [:dual, :not_dual]

  # see scopes
  scope :dual, -> {where(status:  Contact.statuses['dual']) }
  scope :not_dual, -> {where(status:  Contact.statuses['not_dual']) }
end

现在进行控制台,检查用户实例是否具有双重状态的联系人:

2.1.5 :001 > u = User.last
  User Load (0.8ms)  SELECT  "users".* FROM "users"   ORDER BY "users"."id" DESC LIMIT 1
 => #<User id: 1, email: "...", ...> 
2.1.5 :003 > u.contacts.dual
  Contact Load (0.3ms)  SELECT "contacts".* FROM "contacts"  WHERE "contacts"."user_id" = $1 AND "contacts"."status" = 0  [["user_id", 1]]
 => #<ActiveRecord::AssociationRelation []> 
2.1.5 :004 > u.contacts.not_dual
  Contact Load (0.3ms)  SELECT "contacts".* FROM "contacts"  WHERE "contacts"."user_id" = $1 AND "contacts"."status" = 1  [["user_id", 1]]
 => #<ActiveRecord::AssociationRelation []> 

正如你所看到的那样返回空数组,因此在空数组上调用any?将返回false。因为我没有任何与status dual或not_dual的联系,所以让我们创建一个。

寻找联系人:

2.1.5 :005 > c = Contact.last
  Contact Load (0.5ms)  SELECT  "contacts".* FROM "contacts"   ORDER BY "contacts"."id" DESC LIMIT 1
  => #<Contact id: 3, user_id: 1, ..., ...., status: nil> 

将其设为双重:

2.1.5 :006 > c.dual!
   (0.1ms)  BEGIN
  SQL (15.1ms)  UPDATE "contacts" SET "status" = $1, "updated_at" = $2 WHERE "contacts"."id" = 3  [["status", 0], ["updated_at", "2014-12-29 13:16:45.576778"]]
   (25.5ms)  COMMIT
 => true

现在检查用户是否有双重或非正式联系人:

2.1.5 :009 > u.contacts.dual.any?
   (0.2ms)  SELECT COUNT(*) FROM "contacts"  WHERE "contacts"."user_id" = $1 AND "contacts"."status" = 0  [["user_id", 1]]
 => true 
2.1.5 :010 > u.contacts.not_dual.any?
   (0.3ms)  SELECT COUNT(*) FROM "contacts"  WHERE "contacts"."user_id" = $1 AND "contacts"."status" = 1  [["user_id", 1]]
 => false 
2.1.5 :011 > 

检查用户实例是否有dual枚举返回true。在您的情况下,而不是用户,它将是sill_colour

如果您不喜欢范围,可以使用where

u.contacts.where(status: Contact.statuses['dual']).any?
=> true

http://edgeapi.rubyonrails.org/classes/ActiveRecord/Enum.html

class Dual < ActiveRecord::Base
  enum status: [:dual, :not_dual]
end

如上所述,你可以检查这样的状态:

dual = Dual.find(params[:id])
dual.dual? # will return true or false depends on the status you set.
dual.not_dual? # same, true or false
dual.status = "dual" # if status was set to 0 or not_dual if status was set to 1