Вы получаете ArgumentError: неправильное количество аргументов (1 вместо 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
. Это происходит для всех типов: объектных, числовых, дат, строк и т. Д. (См. Код 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]) }
Переопределите не to_json, а as_json. А из as_json вызовите то, что хотите:
Попробуйте следующее:
def as_json
{ :username => username, :foo => foo, :bar => bar }
end