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

Ruby on Rails ternary operator to display BOTH nil and false

我有 3 个用户角色,分别称为标准、高级和管理员。每个可以post posts。 Premium 和管理员可以选择是私有 post 还是非私有 post(私有:false 或私有:true)。标准用户将无法选择他们的 Post 是否私密;默认情况下,所有标准用户的 post 都将具有 Private: nil 状态。

总结一下:

我正在尝试创建一个范围,以便当标准用户查看索引页面时,他们会看到 posts 的 Private: nil 和 Private: false,而高级和管理员用户可以查看所有内容。我的问题是,我想不出允许标准用户同时查看 private: nil 和 private: false Posts.

的三元运算符

这是我在 Post 型号上的:

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

上面的代码只显示 Posts with private: false。 我尝试了各种组合:

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

仅显示私有:false posts

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

仅显示私人:无 posts

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

仅显示私人:无 posts

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

仅显示私有:false posts

和其他几种组合 -

我也注意到当我调换false和nil的顺序时,显示的结果不同。我以为||或 && 运算符是 不可交换的 。也许有一些我不知道的关于作用域或三元运算符的东西......

谢谢!

对我来说,作用域更多的是为了传达您的数据模型的一部分。其逻辑应该在模型或控制器中,具体取决于您的设置和偏好。这是一般性建议。

对于 nil 值,我会为该列设置一个默认值并将所有当前的 nil 值迁移为 false。对这些有确定的价值,而不是推断 nil 意味着错误或未定,这将使您的生活更轻松。

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

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

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

听起来您只是想知道如何在 where 中执行 or 运算符? http://guides.rubyonrails.org/active_record_querying.html

第 2.3.3 节子集条件

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

这应该将其转换为 sql

WHERE private in (false, nil)

对于 sql 中的多个 or 语句,这是 shorthand。 您还可以将 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)