【发布时间】:2013-07-02 16:36:41
【问题描述】:
有没有一种方法可以指定选择 ActiveRecord 中的所有列,除了几个。例如,对于用户,我不想选择他们的密码哈希或电子邮件。这是可能的还是我必须手动硬编码所有列?
谢谢
【问题讨论】:
标签: ruby-on-rails ruby activerecord
有没有一种方法可以指定选择 ActiveRecord 中的所有列,除了几个。例如,对于用户,我不想选择他们的密码哈希或电子邮件。这是可能的还是我必须手动硬编码所有列?
谢谢
【问题讨论】:
标签: ruby-on-rails ruby activerecord
写一个类似的范围
def select_without columns
select(column_names - columns.map(&:to_s))
end
【讨论】:
def select_without *columns 这样你就可以接受任意数量的参数
COUNT 在这里不起作用。所以,Model.select([:a,:b]).count 会抛出一个错误
column_names?
column_names 是一个类方法。
.size。我不是 SQL 专家,但在 select 中放置多个列会导致您看到的错误。 COUNT 是相当低级的 SQL。我相信您必须使用“窗口功能”才能使其在这种情况下工作。像select *, count(*) over () as total_count from mytable 这样的东西。在这种情况下,size 对我有用,但我认为它可能不如 count 或 length 准确。
这样的?
exclude_columns = ['password', 'email']
columns = User.attribute_names.delete_if(|x| exclude_columns.include?(x))
User.select(columns)
编辑
我忘了我们可以做 Array1 - Array2
最佳答案:
exclude_columns = ['password', 'email']
columns = User.attribute_names - exclude_columns
User.select(columns)
【讨论】:
delete_if 应该有花括号。
另一种非常有用的方法是在模型内部使用范围,以防您需要不断避免列。
在我的例子中,我将图像保存到 blob 字段中,因此我想避免每次都以一种简单的方式加载这些图像:
scope :select_exclude_image, -> { select( Movie.attribute_names - ['image'] ) }
然后为了避免选择中的图像,您可以执行以下操作:
Movie.select_exclude_image.first
或
Movie.select_exclude_image.all
希望对你有帮助!
【讨论】:
只需为希望在每个查询中默认排除某些列的人添加一个选项,就可以使用 Rails 5 功能ignored_columns,顾名思义,将这些排除在外。
代码很简单:
class User < ApplicationRecord
self.ignored_columns = %w[password email]
end
请注意,ignore_columns documentation 声明 You will get an error if accessing that attribute directly, so ensure all usages of the column are removed,因此它可能仅适用于从不需要使用列的情况。
【讨论】:
在某些情况下,特别是当您考虑使用default_scope 排除某些列时,我建议您不要使用这种方法,因为在select 子句之后,带有Rails 的count 会中断known issue。这可能会导致令人惊讶的下游错误。
在这种情况下,请考虑将您的记录分成两张表,一张包含基本数据,另一张包含您不时需要的数据,然后使用关联来访问额外数据。
【讨论】: