Rails 3 отвечает на вопрос в формате json

#ruby-on-rails #json #activerecord #respond-with

#ruby-on-rails #json #activerecord #ответить-с

Вопрос:

Возникли проблемы с генерацией некоторого json. Я пытаюсь отобразить результат одной активной записи в json следующим образом:

 @data = User.find(1)
respond_with(@data, :include => :status)
  

Результатом json является:

 {
  -user: {
    address: null
    email: "test@email.com"
    first_name: "Test"
    last_name: "Man"
    status_id: 1
    username: "testguy"
    status: { }
  }
}
  

Так в чем проблема? Проблема в том, что статус :include=>: кажется
чтобы не портить отношения. В моей пользовательской модели у меня есть
belongs_to :статус. Как мне заставить это работать с одним результирующим набором?

Когда я делаю это:

 @data = User.where("id = 1")
respond_with(@data, :include => :status)
  

Таким образом, соотношение отображается в результирующем наборе json. Но его
внутри массива объектов, которые мне не нужны.

Есть идеи?

Ответ №1:

Я предполагаю, что статус, который вы хотите включить, не является ни одним из кодов состояния http (200, 201 и т.д.), Ни объектом, каким-либо образом связанным с объектом User, И является вашей собственной переменной.

Используя Rails 3.0.10 и Ruby 1.9.2, вы можете найти одно из этих двух решений, подходящее для вас. Вместо этого respond_with используйте render следующее.

Решение 1

 render :json => {:data => @data, :status => "whatever"}
  

Результатом json является:

 {
  data:
  {
    user:
    {
      address: null
      email: "test@email.com"
      first_name: "Test"
      last_name: "Man"
      status_id: 1
      username: "testguy"
    }
  }
  status: "whatever"
}
  

Решение 2

 render :json => {:user => {:address => @data.address, :email => @data.email, ..., :status => "whatever"}}
  

Результатом json является:

 {
  user:
  {
    address: null
    email: "test@email.com"
    ...
    status: "whatever"
  }
}
  

Я надеюсь, это то, что вы искали.

Ответ №2:

Похоже, вы испытываете примерно те же страдания, что и я, при использовании встроенной сериализации rails. В итоге я использовал шаблоны RABL, которые намного упростили мою жизнь. Если вам нужно руководство по быстрому запуску с RABL, я собрал его вместе:

http://blog.dcxn.com/2011/06/22/rails-json-templates-through-rabl/

Ответ №3:

where возвращает массив, поэтому ваши результаты имеют смысл. Вам понадобится where().first , или, поскольку это просто поиск идентификатора, просто используйте find .

Это было давно, но, тем не менее, это самый краткий ответ:

 @data = User.find(1)
respond_with(@data, :include => :status)
  

Комментарии:

1. у меня это отлично работает (а именно, указание :include в respond_with вызове), но, похоже, я не могу найти никакой документации для этого, даже в responders gem README. как вы узнали, что нужно использовать эту функцию?

Ответ №4:

Возможно, вы уже решили его, приятель, но если вы все еще сталкиваетесь с проблемами, вы можете сделать это таким образом, если хотите?

 @data = User.find(1, :include => :status)

respond_to do |format|
  format.json do
    render @data.to_json(:include => :status)
  end
end
  

Если это не сработает, возможно, что-то не так с вашими ассоциациями. В api есть действительно хороший раздел о «быстрой загрузке ассоциаций» здесь:

http://apidock.com/rails/ActiveRecord/Associations/ClassMethods

Комментарии:

1. Нет .. пробовал это. Ничего хорошего. Я все еще получаю пустой объект status в ответе json. Я знаю, что связь работает, потому что, если я запускаю @data.status в обычном представлении, я получаю объект.

Ответ №5:

Как указал Никстерримус, RABL — это действительно правильный путь. Это просто, чисто и элегантно. Я относительно новичок в rails и не использовал эти методы (to_json и т.д.), Но, проведя некоторые исследования и фактически используя RABL, я не могу не задаться вопросом, почему это не является встроенной функцией Rails.