Как переопределить json в Rails?
обновление:
этот вопрос не был должным образом изучены. Реальная проблема лежит в пределах render :json.
первая вставка кода в исходном вопросе даст ожидаемый результат. Однако, есть еще один нюанс. См. этот пример:
render :json => current_user
и не то же самое, что
render :json => current_user.to_json
то есть render :json не будет автоматически вызывать to_json метод, связанный с пользователем объект. в самом деле, если to_json переопределяется на User модель render :json => @user создает ArgumentError описано ниже.
резюме
# works if User#to_json is not overridden
render :json => current_user
# If User#to_json is overridden, User requires explicit call
render :json => current_user.to_json
все это кажется глупым. Это, кажется, говорит мне, что render на самом деле не называя Model#to_json когда типа это. Может кто-нибудь объяснить, что здесь происходит?
любой гений, который может помочь мне в этом, скорее всего, ответит на мой другой вопрос: Как построить Ответ JSON путем объединения @foo.to_json(options) и @bars. to_json(options) в Rails
Исходный Вопрос:
Я видел некоторые другие примеры, но я не делаю то, что я ищу.
Я пытаюсь:
class User < ActiveRecord::Base
# this actually works! (see update summary above)
def to_json
super(:only => :username, :methods => [:foo, :bar])
end
end
Я ArgumentError: wrong number of arguments (1 for 0) на
/usr/lib/ruby/gems/1.9.1/gems/activesupport-2.3.5/lib/active_support/json/encoders/object.rb:4:in `to_json
какие идеи?
4 ответов:
вы получаете
ArgumentError: wrong number of arguments (1 for 0), потому чтоto_jsonдолжен быть переопределен с одним параметром,optionsхэш.def to_json(options) ... end
больше объяснений
to_json,as_json, и рендеринг:В ActiveSupport 2.3.3,
в любое времяas_jsonбыл добавлен для решения проблем, подобных той, с которой вы столкнулись. Элемент создание json должен быть отделен от визуализация из json.to_jsonвызывается на объект,as_jsonвызывается для создания структуры данных, а затем этот хэш кодируется как строка JSON с помощьюActiveSupport::json.encode. Это происходит для всех типов: object, numeric, date, string и т. д. (см. код ActiveSupport).объекты ActiveRecord ведут себя точно так же. Есть значение по умолчанию
as_jsonреализации, что создает хэш, который включает в себя все атрибуты модели. вы должны переопределитьas_jsonв вашей модели для создания структуры JSON вы хотите.as_json, если быto_json, принимает параметр хэш, где можно указать атрибуты и методы для включения декларативно.def as_json(options) # this example ignores the user's options super(:only => [:email, :handle]) endв свой контроллер,
render :json => oможет принимать строку или объект. если это строка, она передается как тело ответа, если это объект,to_jsonназывается, который запускаетas_jsonкак описано выше.Итак, пока ваши модели правильно представлены с
as_jsonпереопределяет (или нет), ваш код контроллера для отображения одной модели должен выглядеть так:format.json { render :json => @user }мораль этой истории такова: избежать вызова
to_jsonнапрямую, позволяютrenderчтобы сделать это для вас. Если вам нужно настроить вывод JSON, позвонитеas_json.format.json { render :json => @user.as_json(:only => [:username], :methods => [:avatar]) }
Если у вас возникли проблемы с этим в Rails 3, переопределите
serializable_hashвместоas_json. Это позволит получить форматирование XML бесплатно тоже :)это заняло у меня навсегда, чтобы выяснить. Надеюсь, это кому-то поможет.
для людей, которые не хотят игнорировать параметры пользователей, но также добавить их:
def as_json(options) # this example DOES NOT ignore the user's options super({:only => [:email, :handle]}.merge(options)) endнадеюсь, это поможет кто-нибудь :)
переопределить не to_json, а as_json. И от as_json назовите то, что вы хотите:
попробуйте это:
def as_json { :username => username, :foo => foo, :bar => bar } end
Comments