【问题标题】:ActiveRecord select except columnsActiveRecord 选择除列
【发布时间】:2013-07-02 16:36:41
【问题描述】:

有没有一种方法可以指定选择 ActiveRecord 中的所有列,除了几个。例如,对于用户,我不想选择他们的密码哈希或电子邮件。这是可能的还是我必须手动硬编码所有列?

谢谢

【问题讨论】:

    标签: ruby-on-rails ruby activerecord


    【解决方案1】:

    写一个类似的范围

    def select_without columns
      select(column_names - columns.map(&:to_s))
    end
    

    【讨论】:

    • 我会做def select_without *columns 这样你就可以接受任意数量的参数
    • 此方法存在问题:COUNT 在这里不起作用。所以,Model.select([:a,:b]).count 会抛出一个错误
    • 这是什么column_names
    • @bpromas column_names 是一个类方法。
    • @VitalyDyatlov 你可以使用.size。我不是 SQL 专家,但在 select 中放置多个列会导致您看到的错误。 COUNT 是相当低级的 SQL。我相信您必须使用“窗口功能”才能使其在这种情况下工作。像select *, count(*) over () as total_count from mytable 这样的东西。在这种情况下,size 对我有用,但我认为它可能不如 countlength 准确。
    【解决方案2】:

    这样的?

    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 应该有花括号。
    【解决方案3】:

    另一种非常有用的方法是在模型内部使用范围,以防您需要不断避免列。

    在我的例子中,我将图像保存到 blob 字段中,因此我想避免每次都以一种简单的方式加载这些图像:

    scope :select_exclude_image, ->  { select( Movie.attribute_names - ['image'] ) }
    

    然后为了避免选择中的图像,您可以执行以下操作:

    Movie.select_exclude_image.first
    

    Movie.select_exclude_image.all
    

    希望对你有帮助!

    【讨论】:

      【解决方案4】:

      只需为希望在每个查询中默认排除某些列的人添加一个选项,就可以使用 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,因此它可能仅适用于从不需要使用列的情况。

      【讨论】:

        【解决方案5】:

        在某些情况下,特别是当您考虑使用default_scope 排除某些列时,我建议您不要使用这种方法,因为在select 子句之后,带有Rails 的count 会中断known issue。这可能会导致令人惊讶的下游错误。

        在这种情况下,请考虑将您的记录分成两张表,一张包含基本数据,另一张包含您不时需要的数据,然后使用关联来访问额外数据。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-11-12
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多