Как я могу активировать ActiveRecord, также возвращать имя столбца для рендеринга в json?

def jsontest
   @users = User.all.limit(10)
   render json: @users
end

дает

{
...

"id": 7,
"name": "Sage Smith",
"email": "[email protected]",
"created_at": "2013-10-17T02:29:15.638Z",
"updated_at": "2013-10-17T02:29:15.638Z",
"password_digest": "$2a$10$taHk3udtWN61Il5I18akj.E90AB1TmdL1BkQBKPk/4eZ7YyizGOli",
"remember_token": "118f807d0773873fb5e4cd3b5d98048aef4f6f59",
"admin": false

...
}

Но я хотел бы опустить некоторые определенные поля из этого API, поэтому я использую pluck

def jsontest
  @users = User.all.limit(10).pluck(:id, :name, :email, :created_at) ###
  render json: @users
end

но pluck возвращает массив только значений, когда я хотел бы иметь атрибуты каждого объекта, доступные с помощью хеш-ключа.

[
...

    7,
    "Sage Smith",
    "[email protected]",
    "2013-10-17T02:29:15.638Z"

...    

]

Итак, как я могу эффективно вырвать значения и их ключи?

Я понимаю, что могу пронестись через @users и захватить ключи, прежде чем выщипывать и воссоздавать хэш, но я ожидаю, что будет какой-то удобный метод, который сделает именно то, что я хочу.

Ответ 1

Используйте select вместо pluck:

def jsontest
  @users = User.select('id, name, email, created_at').limit(10)
  render json: @users
end

Ответ 2

Ответ на вопрос хорош, но у меня есть одно предостережение. select создает экземпляр User для каждой строки результата, но pluck - нет. Это не имеет значения, если вы возвращаете только несколько объектов, но если вы возвращаете большие партии (50, 100 и т.д.), Вы заплатите значительное снижение производительности.

Я столкнулся с этой проблемой, и я переключился назад, чтобы сорвать:

#in user.rb
def self.pluck_to_hash(keys)
  pluck(*keys).map{|pa| Hash[keys.zip(pa)]}
end

#in elsewhere.rb
User.limit(:10).pluck_to_hash(['id, name, email, created_at'])

Это некрасиво, но он получает хэш, который вы хотите, и быстро.

Я обновил его, чтобы отразить комментарий Майка Кэмпбелла 11 октября.

Ответ 3

Создал простой pluck_to_hash камень для достижения этого. https://github.com/girishso/pluck_to_hash

Пример использования.

Post.limit(2).pluck_to_hash([:id, :title])
#
# [{:id=>213, :title=>"foo"}, {:id=>214, :title=>"bar"}]
#

Post.limit(2).pluck_to_hash(:id)
#
# [{:id=>213}, {:id=>214}]
#

# Or use the shorter alias pluck_h

Post.limit(2).pluck_h(:id)
#
# [{:id=>213}, {:id=>214}]
#

Ответ 4

Самый быстрый способ возврата хэша пользователей с выбранными столбцами - использовать ActiveRecord::Base.connection.select_all.

sql = User.select('id, name, email, created_at').limit(10).to_sql
@users = ActiveRecord::Base.connection.select_all(sql)
render json: @users

Ответ 5

@girishso gem отлично, но мой проект находится в Rails 3. Он не работает.

Эта статья полезна для меня или устанавливает pluck_all, чтобы достичь этого.

Использование:

User.limit(10).pluck_all(:id, :name, :email, :created_at)

Ответ 6

@andrewCone - это должно быть так:

User.limit(:10).pluck_to_hash([:id, :name, :email, :created_at])