Ruby on Rails 3 - to_json, не включая все атрибуты
Я использую метод to_json
для моего объекта модели, который я создал, делая что-то вроде:
user = User.find(1)
Когда я делаю user.to_json
, отсутствует множество атрибутов, включая user.id
из закодированной строки JSON. Похоже, что все атрибуты, которые я добавил как attr_accessible из модели User, есть, но ни один из других. Возможно, это то, что делает to_json, но я думаю, что добавление id
в attr_accessible - это не выход.
Каков правильный способ решения этой проблемы?
ОБНОВЛЕНИЕ
Это выглядит как проблема с Devise. Если я комментирую следующее из user.rb, все работает так, как ожидалось:
devise :rememberable, :trackable, :token_authenticatable, :omniauthable
Ответы
Ответ 1
Я не проверял, но считаю, что Devise делает это за вас; он включает только определенные атрибуты через attr_accessible.
В любом случае правильный способ решить это - переопределить метод as_json
следующим образом:
def as_json(options = nil)
{
my_attr: my_attr,
etc: etc
}
end
Это простой хеш, и это действительно мощный метод для генерации JSON в AR без использования метода to_json
.
Ответ 2
По умолчанию Devise переопределяет метод serializable_hash, чтобы выставлять только доступные атрибуты (так что такие вещи, как encrypted_password, по умолчанию не передаются по API-интерфейсам).
Вы можете попытаться переопределить этот метод и добавить auth_token в хеш, что-то вроде этого:
def serializable_hash (options = nil) super (options).merge( "auth_token" = > auth_token)
конец
Ответ 3
Разработчик действительно фильтрует атрибуты для вас, как упомянуто kain.
Тем не менее, я предпочел бы просто добавить то, что мне нужно, вместо того, чтобы переопределять логику Devise.
Вместо этого я предпочел бы сделать
def as_json(options={})
json_res = super options
json_res['locked_at'] = self.locked_at
json_res['confirmed_at'] = self.confirmed_at
end
или любые другие атрибуты, которые может иметь ваш пользователь, который вы хотите передать
Ответ 4
Если вы пришли сюда в поисках Rails 4, как и я, здесь немного информации, которая поможет.
Как сказал выше Алан Дэвид Гарсия, Devise переопределяет serializable_hash
. Чтобы заставить переопределить, вы можете сделать следующее, например, для возврата всех атрибутов, кроме password_digest
при вызове Model#as_json
.
def as_json(options = {})
options[:force_except] ||= [:password_digest]
super(options)
end
Вы можете указать любые желаемые атрибуты модели для исключения в options[:force_except]
вместо :password_digest
.
Ответ 5
включить в класс модели что-то вроде этого:
attr_accessible :id, :email, :password, :password_confirmation, :remember_me
Изначально id не был включен в json, но после того, как я добавил его в attr_accessible, он сработал.