Указание атрибутов объекта Rails, переданного в объект JSON

У меня есть объект в Rails, который имеет атрибуты A, B, C, D и E. При передаче этого объекта на клиентскую сторону через объект JSON, как я могу сказать контроллеру рельсов включать только атрибуты A и D в объекте JSON?

В моем контроллере Users мой код выглядит следующим образом:

    @user = User.find(params[:id])

    respond_to do |format|
        format.html
        format.json { render :json => @user}
    end

Этот код работает, однако возвращенный объект JSON содержит все атрибуты объекта @user. Как ограничить атрибуты, включенные в объект JSON, прежде чем что-либо будет отправлено обратно клиенту?

UPDATE: lucapette дает хороший фон о том, что происходит за кулисами. Поскольку бывают случаи, когда я, вероятно, хочу вернуть все атрибуты, я закончил использовать следующий код:

    format.json { render :json => @user.to_json(:only => ["id"])}

Ответ 1

render :json => @user

вызовет to_json в объекте @user. И метод to_json будет использовать метод as_json для выполнения своей работы. Таким образом, вы можете легко переопределить as_json, чтобы передать только то, что вы хотите для клиентов. Как в следующем:

def as_json options={}
  {
    attr1: attr1,
    attr2: attr2
  }
end

Ответ 2

Хороший путь здесь Как выбрать только определенные атрибуты из модели? используя select, чтобы просто получить определенные атрибуты.

Курс

Off работает только в том случае, если вам не нужны другие атрибуты в коде. Как общий способ атаковать эту проблему, rabl стоит посмотреть https://github.com/nesquena/rabl

Ответ 3

Переопределите метод as_json в вашей модели, чтобы включить ассоциации, скрыть столбцы и почему нет? вызов пользовательских методов, поскольку они были атрибутами

  def as_json(options={})
    super(:except => [:created_at,:updated_at],
          :include => { 
            :members => {
                :only => [:role, :account], 
                :include => {
                  :account => {
                    :only => [:name, :subdomain]
                  }
                }
              }
            },
          :methods => [:jwt_token]
    )
  end

Это выведет что-то вроде этого:

{
  "id": 2,
  "name": "Test Teacher",
  "email": "[email protected]",
  "jwt_token":"eyJhbGciOiJIUzI1NiJ9.eyJpZCI6MiwiZXhwIjoxNTY2NzQ0OTQzfQ.HDGu7JiJEQEEpGo7inuXtOZBVQOfTaFquy8dr-QH5jY",

  "members": [{
        "role": "instructor",
        "account": {
            "name": "Testing",
            "subdomain": "test"
         }
  }],
}