【问题标题】:Why does Rails .select alias change attributes to lowercase?为什么 Rails .select 别名将属性更改为小写?
【发布时间】:2016-12-09 14:46:08
【问题描述】:

在我们的控制器中,我们正在尝试显示一个视频系列,它应该返回类似于以下内容的 JSON:

{
  id:   1,
  name: "Series Name",
  videos: [
    id:           2,
    name:         "Video Name",
    isInPlaylist: true,
    isFavorite:   false
  ]
}

我们正在通过另一个表添加 isInPlaylist 和 isInFavorite 属性,如果用户对视频进行了操作(评分、收藏等),我们将在该表中存储数据。

videos = series.videos
           .where('videos.is_live = true')
           .joins("some join to user_videos join_table")
            .select(
               'videos.*,
               coalesce(user_videos.rating, 0.0) as user_rating,
               coalesce(user_videos.enqueue, \'false\') as isInPlaylist,
               coalesce(user_videos.favorite, \'false\') as isFavorite'
             )

请注意,在我们的 select 语句中,这些属性显式别名为驼峰式值。然而,当我们执行这个查询时,这些属性会以小写形式返回:

{
  isinplaylist: true,
  isfavorite:   false
}

【问题讨论】:

    标签: sql ruby-on-rails postgresql ruby-on-rails-4 rails-postgresql


    【解决方案1】:

    这不是 Rails 行为,而是 SQL 行为。除非明确引用,否则别名将折叠为小写。例如,这里是 psql(Postgres CLI 程序)中一个简单查询的输出。

    =# select created_at as theTimeNow from users limit 5;
             thetimenow         
    ----------------------------
     2013-03-05 18:45:11.127092
     2013-09-07 16:43:01.349823
     2013-03-05 18:53:35.888306
     2013-09-07 16:53:06.553129
     2013-10-29 00:38:56.909418
    (5 rows)
    
    
    =# select created_at as "theTimeNow" from users limit 5;
             theTimeNow         
    ----------------------------
     2013-03-05 18:45:11.127092
     2013-09-07 16:43:01.349823
     2013-03-05 18:53:35.888306
     2013-09-07 16:53:06.553129
     2013-10-29 00:38:56.909418
    (5 rows)
    

    注意列名输出

    【讨论】:

    • 是的,经过更多研究发现它在 DB 中发生的位置。感谢您的回答!
    【解决方案2】:

    将别名用双引号括起来可以保持区分大小写。

    .select('foo as Bar') # => { bar: true }

    .select('foo as "Bar"') # => { Bar: true }

    更改为小写不是 Rails .select() 方法的问题,而是由数据库强制执行,在我们的例子中是 PostgreSQL,并且是一种称为“折叠”的做法。值得注意的是,虽然 PSQL 会折叠成小写字母,但 mySQL 会折叠成大写字母。

    但我认为它仍应包含在 Rails API 文档中 ¯\_(ツ)_/¯

    【讨论】:

      【解决方案3】:

      我喜欢你的回答。您看到的行为是 rails 默认行为。作为替代方案和 更经典的“rails 方式”是使用像jBuilder 这样的 json 序列化库。它使您可以更好地控制 API,但您的问题很容易解决:

      json.key_format! camelize: :lower
      json.first_name 'David'
      
      # => { "firstName": "David" }
      

      要使用类似的内容,您可以将列别名为is_in_playlist 格式。

      这里是开始学习 jBuilder 的好地方:

      http://railscasts.com/episodes/320-jbuilder

      关于更多 json 序列化器的好教程:

      http://railscasts.com/episodes/409-active-model-serializers

      【讨论】:

      • 感谢肖纳克的建议。我唯一担心的是,我们必须遍历循环才能使用 jBuilder 解决方案,因为这些是通过连接表大量嵌套的属性。使用 as_json 包含和别名似乎比 IMO 更干净。然而,我在 Rails API 中没有看到任何内容指出这是一个强制约定,我认为这是一个文档问题,无论这是 SQL 决定还是 Rails。
      猜你喜欢
      • 2019-02-26
      • 1970-01-01
      • 2021-02-12
      • 1970-01-01
      • 2017-06-24
      • 1970-01-01
      • 2021-10-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多