在我的Post.rb
型号上,我有这个:
class Post < ActiveRecord::Base
belongs_to :user
enum is_published: [ :no, :yes ]
scope :published, -> { where( is_published: "yes") }
scope :unpublished, -> { where( is_published: "no") }
end
但是当我尝试在我的控制台中执行此操作时,它会给我错误的结果:
> Post.published.count
(0.7ms) SELECT COUNT(*) FROM "posts" WHERE "posts"."is_published" = 0
=> 5
> Post.published
Post Load (1.0ms) SELECT "posts".* FROM "posts" WHERE "posts"."is_published" = 0
=> #<ActiveRecord::Relation [#<Post id: 20, title: "Chang calls for immediate removal of Davies, JUTC ...", photo: nil, body: "Opposition spokesperson on Transport, Horace Chang...", created_at: "2014-08-30 11:07:05", updated_at: "2014-08-30 20:03:56", user_id: 1, ancestry: nil, file: "Davies-Must-Go.pdf", status: 0, slug: "chang-calls-for-immediate-removal-of-davies-jutc-m...", is_published: 0, has_eyewitness: false>, #<Post id: 21, title: "PNP Chairman expresses shock, grief at Clarke’s pa...", photo: nil, body: "Chairman of the People’s National Party (PNP), the...", created_at: "2014-08-30 13:22:05", updated_at: "2014-08-30 20:03:56", user_id: 1, ancestry: nil, file: nil, status: 1, slug: "pnp-chairman-expresses-shock-grief-at-clarke-s-pas...", is_published: 0, has_eyewitness: false>, #<Post id: 22, title: "ALGAJ Pays Tribute to the Honourable Roger Clarke", photo: nil, body: "The Association of Local Government Authorities of...", created_at: "2014-08-30 16:19:12", updated_at: "2014-08-30 20:03:56", user_id: 1, ancestry: nil, file: nil, status: 2, slug: "algaj-pays-tribute-to-the-honourable-roger-clarke", is_published: 0, has_eyewitness: false>, #<Post id: 26, title: "PNPYO saddened at passing of Roger Clarke", photo: nil, body: "The People’s National Youth Organisation (PNPYO), ...", created_at: "2014-08-30 19:50:47", updated_at: "2014-08-30 19:50:47", user_id: 1, ancestry: nil, file: nil, status: 1, slug: "pnpyo-saddened-at-passing-of-roger-clarke", is_published: 0, has_eyewitness: false>, #<Post id: 25, title: "10PP 1 on 2", photo: "1-on-1-Icon.jpg", body: "10PP gives you a lot of one on one attention that ...", created_at: "2014-08-30 17:35:17", updated_at: "2014-08-30 20:09:05", user_id: 1, ancestry: nil, file: nil, status: 0, slug: "10pp-1-on-2", is_published: 0, has_eyewitness: false>]>
> Post.published.first.is_published
Post Load (3.6ms) SELECT "posts".* FROM "posts" WHERE "posts"."is_published" = 0 ORDER BY "posts"."id" ASC LIMIT 1
=> "no"
如您所见,从Post.published
返回的AR关系中的第一个对象实际上具有"no"
的值。
同样,如果我做Post.unpublished
,我会得到相同的数据集:
> Post.unpublished.count
(0.7ms) SELECT COUNT(*) FROM "posts" WHERE "posts"."is_published" = 0
=> 5
> Post.unpublished
Post Load (0.6ms) SELECT "posts".* FROM "posts" WHERE "posts"."is_published" = 0
=> #<ActiveRecord::Relation [#<Post id: 20, title: "Chang calls for immediate removal of Davies, JUTC ...", photo: nil, body: "Opposition spokesperson on Transport, Horace Chang...", created_at: "2014-08-30 11:07:05", updated_at: "2014-08-30 20:03:56", user_id: 1, ancestry: nil, file: "Davies-Must-Go.pdf", status: 0, slug: "chang-calls-for-immediate-removal-of-davies-jutc-m...", is_published: 0, has_eyewitness: false>, #<Post id: 21, title: "PNP Chairman expresses shock, grief at Clarke’s pa...", photo: nil, body: "Chairman of the People’s National Party (PNP), the...", created_at: "2014-08-30 13:22:05", updated_at: "2014-08-30 20:03:56", user_id: 1, ancestry: nil, file: nil, status: 1, slug: "pnp-chairman-expresses-shock-grief-at-clarke-s-pas...", is_published: 0, has_eyewitness: false>, #<Post id: 22, title: "ALGAJ Pays Tribute to the Honourable Roger Clarke", photo: nil, body: "The Association of Local Government Authorities of...", created_at: "2014-08-30 16:19:12", updated_at: "2014-08-30 20:03:56", user_id: 1, ancestry: nil, file: nil, status: 2, slug: "algaj-pays-tribute-to-the-honourable-roger-clarke", is_published: 0, has_eyewitness: false>, #<Post id: 26, title: "PNPYO saddened at passing of Roger Clarke", photo: nil, body: "The People’s National Youth Organisation (PNPYO), ...", created_at: "2014-08-30 19:50:47", updated_at: "2014-08-30 19:50:47", user_id: 1, ancestry: nil, file: nil, status: 1, slug: "pnpyo-saddened-at-passing-of-roger-clarke", is_published: 0, has_eyewitness: false>, #<Post id: 25, title: "10PP 1 on 2", photo: "1-on-1-Icon.jpg", body: "10PP gives you a lot of one on one attention that ...", created_at: "2014-08-30 17:35:17", updated_at: "2014-08-30 20:09:05", user_id: 1, ancestry: nil, file: nil, status: 0, slug: "10pp-1-on-2", is_published: 0, has_eyewitness: false>]>
> Post.unpublished.first
Post Load (0.6ms) SELECT "posts".* FROM "posts" WHERE "posts"."is_published" = 0 ORDER BY "posts"."id" ASC LIMIT 1
=> #<Post id: 20, title: "Chang calls for immediate removal of Davies, JUTC ...", photo: nil, body: "Opposition spokesperson on Transport, Horace Chang...", created_at: "2014-08-30 11:07:05", updated_at: "2014-08-30 20:03:56", user_id: 1, ancestry: nil, file: "Davies-Must-Go.pdf", status: 0, slug: "chang-calls-for-immediate-removal-of-davies-jutc-m...", is_published: 0, has_eyewitness: false>
> Post.unpublished.first.is_published
Post Load (0.7ms) SELECT "posts".* FROM "posts" WHERE "posts"."is_published" = 0 ORDER BY "posts"."id" ASC LIMIT 1
=> "no"
有趣的是,Post
表中有is_published: "yes"
的1条记录永远不会被返回。
从这里可以看出:
> p = Post.first
Post Load (0.4ms) SELECT "posts".* FROM "posts" ORDER BY "posts"."id" ASC LIMIT 1
=> #<Post id: 1, title: "Fire at Bible College in Christian", photo: nil, body: "A massive fire is now raging at the Bible College ...", created_at: "2014-08-28 08:06:19", updated_at: "2014-09-18 20:56:32", user_id: 1, ancestry: nil, file: nil, status: 0, slug: "fire-at-bible-college-in-christian", is_published: 1, has_eyewitness: true>
> p.is_published
=> "yes"
答案 0 :(得分:1)
检查ActiveRecord::Enum文档显示了范围的以下语法:
class Post < ActiveRecord::Base
belongs_to :user
enum is_published: [ :no, :yes ]
scope :published, -> { where( is_published: Post.is_publisheds[:yes] ) }
scope :unpublished, -> { where( is_published: Post.is_publisheds[:no]) }
end
您的查询显示您正在获取0
以获得&#34;是&#34;这看起来不正确。通过此建议的更改,您应该获得yes
和no
的正确枚举值。另外在附注中,文档说明:
enum属性的条件必须使用a的序数值 枚举。
答案 1 :(得分:1)
tldr; is_published: [:yes, :no]
不适用于enum
。
枚举和使用它的范围有很多错误。
首先,您不能以这种方式使用where
。你完全回避enum
,只是查询列。由于您要查询整数列,Rails会将查询值转换为整数。 "yes"
和"no"
都转换为整数0
,因此这些范围无效。如果您要使用where
,则需要手动生成正确的整数值。对于您的模型,它看起来像这样:
Post.where(is_published: Post.is_publisheds['yes'])
第二,注意is_publisheds
的非常笨拙的复数化;这是一个提示,你的枚举使用了一个坏名称。
第三,您手动制作冗余范围。 Rails已经为您enum
中的每个值提供了范围,但您选择了真正的错误名称。您的模型现在有yes
和no
范围!您可以使用Post.yes
和Post.no
来获取已发布/未发布的记录,但这显然是错误的。
这一切都源于你基本上枚举了一个布尔这一事实。这完全忽略了这一点。如果你真的只是在一个布尔值之后,enum
不合适,你就不应该使用它。只需使用布尔列,并使用where(is_published: true)
和where(is_published: false)
编写一对合理的范围。
如果您想使用枚举,而不是使用is_published
,请使用enum status: [:published, :unpublished]
,甚至enum publication_status: [:published, :unpublished]
。这就是你所需要的一切。 Rails将查看枚举值,并为您生成您想要的两个范围,而无需您做其他工作。
整个班级看起来像这样:
class Post < ActiveRecord::Base
belongs_to :user
enum status: [ :published, :unpublished ]
# No need for scopes, enum gives you published/unpublished scopes already
end