Как переопределить to_json в направляющих?


93
задан Community 23 May 2017 в 12:18
поделиться

2 ответа

Вы получаете 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]) }
208
ответ дан 24 November 2019 в 06:11
поделиться

Переопределите не to_json, а as_json. А из as_json вызовите то, что хотите:

Попробуйте следующее:

def as_json 
 { :username => username, :foo => foo, :bar => bar }
end
3
ответ дан 24 November 2019 в 06:11
поделиться
Другие вопросы по тегам:

Похожие вопросы: