Обновить:
Эта проблема не была изучена должным образом. Настоящая проблема кроется внутри render :json
.
Первая вставка кода в исходный вопрос даст ожидаемый результат. Однако все же есть нюанс. См. Этот пример:
render :json => current_user
это НЕ то же самое,
render :json => current_user.to_json
То есть render :json
не будет автоматически вызывать to_json
метод, связанный с объектом User. Фактически , если 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
указан тип . Может кто-нибудь объяснить, что здесь происходит на самом деле?
Любой гений, который может мне в этом помочь, скорее всего, ответит на мой другой вопрос: как создать ответ JSON, объединив @ foo.to_json (параметры) и @ bars.to_json (параметры) в Rails.
Исходный вопрос:
Я видел несколько других примеров на SO, но я не делаю то, что ищу.
Я стараюсь:
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
Любые идеи?
username
,foo
илиbar
методы ожидают аргументы?username
это не метод , аfoo
иbar
не требуют методов. Я обновил свой вопрос, чтобы показать, где происходит ошибка.Ответы:
Вы получаете,
ArgumentError: wrong number of arguments (1 for 0)
потому чтоto_json
необходимо переопределить одним параметром,options
хешем.Более длинные объяснения
to_json
,as_json
и рендеринга:В ActiveSupport 2.3.3
as_json
был добавлен для решения проблем, подобных той, с которой вы столкнулись. Создание в формате JSON должно быть отделено от оказания в формате JSON.Теперь в любое время
to_json
вызывается для объекта,as_json
вызывается для создания структуры данных, а затем этот хеш кодируется как строка JSON с использованиемActiveSupport::json.encode
. Это происходит для всех типов: объектных, числовых, дат, строк и т. Д. (См. Код ActiveSupport).Объекты ActiveRecord ведут себя точно так же. Существует
as_json
реализация по умолчанию, которая создает хэш, включающий все атрибуты модели. Вы должны переопределитьas_json
в своей модели, чтобы создать нужную структуру JSON .as_json
, как и в предыдущем случаеto_json
, принимает хэш параметров, в котором вы можете указать атрибуты и методы для декларативного включения.В вашем контроллере
render :json => o
может принимать строку или объект. Если это строка, она передается как тело ответа, если это объект,to_json
вызывается,as_json
как описано выше.Итак, пока ваши модели правильно представлены с
as_json
переопределениями (или нет), код вашего контроллера для отображения одной модели должен выглядеть так:Мораль этой истории такова: не звоните
to_json
напрямую, позвольтеrender
сделать это за вас. Если вам нужно настроить вывод JSON, позвонитеas_json
.источник
as_json
. Как вы можете видеть в документации по ActiveRecord :: Serialization ( api.rubyonrails.org/classes/ActiveRecord/… ), документации по этому очень мало (нет). Я попробую :)as_json
документы!Если у вас возникли проблемы с этим в Rails 3, переопределите
serializable_hash
вместоas_json
. Это также бесплатно получит ваше XML-форматирование :)Мне потребовалась целая вечность, чтобы понять. Надеюсь, это кому-то поможет.
источник
serializable_hash
? Когда я его использую, он меняет мой последующий вывод xml, заключающийся в заключении объекта в оболочку с его именем (например, «цитата» для объекта цитаты »), чтобы вместо этого всегда заключать его в« <hash> ».to_xml
Для людей, которые не хотят игнорировать параметры пользователей, но также добавляют свои:
Надеюсь, это кому-нибудь поможет :)
источник
options
хэш,= {}
поэтому он не требуется при звонкеПереопределить не to_json, а as_json. И из as_json вызывайте то, что хотите:
Попробуй это:
источник
as_json
только для ActiveResource?render :json => current_user
получаю ожидаемый результат по умолчанию (все атрибуты дляUser
модели в формате JSON). Когда я добавляюas_json
метод к своейUser
модели и пробую то же самое, я получаю сообщение об ошибке :(