as_json не вызывает as_json для ассоциаций - PullRequest
35 голосов
/ 30 января 2011

У меня есть модель с данными, которые никогда не должны включаться, когда она отображается как json.Поэтому я реализовал метод класса as_json для правильного поведения.Проблема в том, что когда другие модели, связанные с этой моделью, отображают json, мой пользовательский as_json не вызывается.

class Owner < ActiveRecord::Base
  has_one :dog

  def as_json(options={})
    puts "Owner::as_json"
    super(options)
  end  
end

class Dog < ActiveRecord::Base
  belongs_to :owner

  def as_json(options={})
    puts "Dog::as_json"
    options[:except] = :secret
    super(options)
  end  
end

Загрузка среды разработки (Rails 3.0.3)
ruby-1.9.2-p136: 001> d = Dog.first
=> #<Dog id: 1, owner_id: 1, name: "Scooby", secret: "I enjoy crapping everwhere">
ruby-1.9.2-p136: 002> d.as_json
Dog :: as_json
=> {"dog" => {"id" => 1, "name" => "Scooby", "owner_id "=> 1}}
ruby-1.9.2-p136: 004> d.owner.as_json (: include =>: собака)
Owner :: as_json
=> {" owner "=> {"id" => 1, "name" => "Shaggy",: dog => {"id" => 1, "name" => "Scooby", "owner_id" => 1, "secret" => "Мне нравится играть везде"}}}

Спасибо за помощь

Ответы [ 6 ]

21 голосов
/ 22 марта 2011

Это известная ошибка в Rails. (Проблема помечена как закрытая из-за перехода на проблемы Github из предыдущего средства отслеживания ошибок, но это все еще проблема с Rails 3.1.)

8 голосов
/ 27 сентября 2011

Как подтверждено выше, это проблема с базой Rails. Патч для рельсов здесь еще не применен и кажется, по крайней мере, немного спорным, поэтому я не решаюсь применять его локально. Даже если применить его как патч обезьяны, он может потенциально усложнить будущие обновления рельсов.

Я все еще рассматриваю RABL , предложенный выше, это выглядит полезным. На данный момент я бы не хотел добавлять другой язык шаблонов представления в свое приложение. Мои текущие потребности очень малы.

Итак, вот обходной путь, который не требует патча и работает для большинства простых случаев. Это работает, когда as_json метод ассоциации, который вы хотели бы вызвать, выглядит как

def as_json(options={})
  super( <... custom options ...> )
end

В моем случае у меня есть Schedule модель, в которой много Events

class Event < ActiveRecord::Base

  # define json options as constant, or you could return them from a method
  EVENT_JSON_OPTS = { :include => { :locations => { :only => [:id], :methods => [:name] } } }

  def as_json(options={})
    super(EVENT_JSON_OPTS)
  end
end

class Schedule < ActiveRecord::Base
  has_many :events

  def as_json(options={})
    super(:include => { :events => { Event::EVENT_JSON_OPTS } })
  end
end

Если вы следуете руководству, что в любое время :include ассоциация в ваших as_json() методах вы определяете любые опции, которые вам нужны, в качестве константы в модели, на которую ссылаются, это будет работать для произвольных уровней ассоциаций. ПРИМЕЧАНИЕ Мне нужен был только первый уровень ассоциации, настроенный в приведенном выше примере.

2 голосов
/ 04 декабря 2016

Я обнаружил, что serializable_hash работает так же, как вы ожидаете, что as_json будет работать, и всегда вызывается:

  def serializable_hash(options = {})
    result = super(options)
    result[:url] = "http://.."
    result
  end
2 голосов
/ 22 марта 2011

Я столкнулся с той же проблемой. Я хотел, чтобы это работало:

render :json => @favorites.as_json(:include => :location)

Но этого не произошло, поэтому я добавил index.json.erb со следующим:

<% favs = @favorites.as_json.each do |fav| %>
    <% fav["location"] = Location.find(fav["location_id"]).as_json %>
<% end %>
<%= favs.to_json.html_safe %>

Не исправить - просто обойти. Я полагаю, вы сделали то же самое.

1 голос
/ 26 июля 2011

Обновление @ Джон отметил, что это известная ошибка в Rails. Патч для исправления выглядит так: на https://github.com/rails/rails/pull/2200. Тем не менее, вы можете попробовать RABL, потому что это мило.

Я всегда был разочарован передачей сложного набора параметров для создания желаемых JSON-представлений. Ваша проблема, с которой я столкнулся в Mongoid в Rails 3.0.9, побудила меня написать шаблоны JSON. Но на самом деле, если вы имеете дело с отношениями или пользовательскими свойствами API, получается, что шаблоны намного лучше.

Кроме того, мне кажется, что работа с различными выходными данными выглядит как слой View, поэтому Я остановился на использовании RABL , языка шаблонов API. Это упрощает создание корректного JSON и включите любые ассоциации или поля.

Не решение проблемы, а лучшее решение для варианта использования.

0 голосов
/ 22 марта 2011
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...