ActiveRecord .select():可以清除旧选择吗?

mko*_*kon 24 ruby-on-rails-3

有没有办法清除.select("table.col1,...")语句中的旧选择?

背景:

我有一个范围,为给定的用户ID请求可访问的项目(简化)

    scope :accessible, lambda { |user_id|
  joins(:users).select("items.*")
    .where("items_users.user_id = ?) OR items.created_by = ?", user_id, user_id)
}
Run Code Online (Sandbox Code Playgroud)

然后例如在索引操作中我只需要项目ID和标题,所以我会这样做:

@items = Item.accessible(@auth.id).select("polls.id, polls.title")
Run Code Online (Sandbox Code Playgroud)

但是,这将选择列"items.,items.id,items.title".我想避免从范围中删除选择,因为那时我必须在其他地方添加一个select("items. ").我是否正确地认为没有办法做到这一点,我或者生活中取得太多的字段或者必须使用多个范围?

Hol*_*lin 52

幸运的是你错了:D,你可以使用该#except方法删除关系所产生的查询的某些部分,所以如果要删除SELECT部分​​,只需执行以下操作:

@items = Item.accessible(@auth.id).except(:select).select("polls.id, polls.title")
Run Code Online (Sandbox Code Playgroud)

  • 这对于了解非常有帮助.在我看来,无论何时应用包含AS别名的`#select`子句(如`User.select("'a'AS abacus")......),你总是需要`除(:select)`在调用`#count`之前.你知道这不是真的任何情况,如果没有,任何想法为什么`#count`不会自动应用`除(:select)`为你?我在工作有一些棘手的地理定位过滤情况,这使我成为一个持续的问题. (5认同)

Mar*_*n13 7

重新选择(Rails 6+)

Rails 6 引入了一个名为 的新方法reselect,它完全满足您的需求,它取代了之前的 setselect语句。

所以现在,您的查询可以写得更短:

@items = Item.accessible(@auth.id).reselect("polls.id, polls.title")
Run Code Online (Sandbox Code Playgroud)