Ruby on Rails三元运算符显示BOTH nil和false

时间:2016-04-30 01:30:59

标签: ruby-on-rails roles ternary-operator scoping

我有3个用户角色,称之为标准,高级和管理员。每个人都可以发帖子。高级和管理员可以选择是发布私人帖子还是非私人帖子(私人:虚假或私人:真实)。标准用户将无法选择他们的帖子是否私密;默认情况下,所有标准用户的帖子都将具有Private:nil状态。

总结:

  • 标准用户的帖子将始终是私密的:nil
  • 高级/管理员用户的帖子可以是私有的:true或private:false

我正在尝试创建一个范围,以便当标准用户查看索引页面时,他们会看到具有Private:nil和Private:false的帖子,而Premium和Admin用户可以查看所有。我的问题是,我不能提出一个三元运算符,允许标准用户同时查看private:nil和private:false帖子。

这就是我在Post模型上的内容:

  scope :visible_to, -> (user) { user.admin? || user.premium? ? all : where(private: false) || where(private: nil)}

上面的代码只显示私有的帖子:false。 我尝试了各种组合:

... where(private: false || nil)}

仅显示私人:虚假帖子

... where(private: nil || false)}

仅显示私人:无帖子

... where(private: nil && false)}

仅显示私人:无帖子

... where(private: false && nil)}

仅显示私人:虚假帖子

和其他几种组合 -

我还注意到,当我切换false和nil的顺序时,它会显示不同的结果。我以为||或者&&运营商非交换。也许有一些我不知道的范围或三元运算符......

谢谢!

2 个答案:

答案 0 :(得分:1)

听起来你只是想知道如何在某个地方做一个或一个操作员? http://guides.rubyonrails.org/active_record_querying.html

第2.3.3节子集条件

... where(private: [false, nil])}

这应该将其转换为sql

WHERE private in (false, nil)

这是sql中多个或语句的简写。 您还可以使用arel表获得更高级的sql功能,而无需分解为纯sql字符串。使用IN和arel示例

查看本文关于您的案例的文章

https://robots.thoughtbot.com/using-arel-to-compose-sql-queries

# It even handles arrays containing nil!
where(foo: ['bar', 'baz', nil]) # => (WHERE foo IN ('bar', 'baz') OR foo IS NULL)

答案 1 :(得分:0)

对我来说,范围更倾向于传达您的数据模型的一部分。根据您的设置和偏好,这个逻辑应该在模型或控制器中。这是一般性建议。

对于nil值,我会为该列设置默认值,并将所有当前的nil值迁移为false。它会让你的生活更容易为这些人带来明确的价值,而不是推断零是指虚假或未定的。

class User 
  def can_view_private_posts
    admin? || premium?
  end
end

class Posts
  scope :private, -> { where(private: false) }
end

然后让您的服务对象或控制器处理能够查看私人帖子的用户之间的关系。