RoR вложенный: включить, чтобы включить подресурсы в to_xml / to_json - PullRequest
19 голосов
/ 14 декабря 2010

У меня странная ситуация с моделью данных, поэтому, возможно, весь мой подход неверен.Вот что я делаю:

У меня есть класс Bird и простой класс Color.Концептуально каждая птица имеет две ассоциации to_many с цветом, одна для мужских цветов и одна для женских.Я справился с этим, используя модель соединения, называемую BirdColoration, которая принадлежит птице и цвету и имеет дополнительное логическое поле, чтобы указать, подходит ли окрас мужской или женской.Таким образом, каждая птица на самом деле имеет отношение to_many к BirdColoration, а также to_many к Color: посредством BirdColoration.Если это звучит разумно, продолжайте чтение.В противном случае, остановитесь и скажите мне, почему это неправильно!

Мне нужно иметь возможность сбросить таблицу птиц как json.Раньше, когда у каждой птицы была только одна связь to_many с цветами, я мог просто использовать: include, чтобы включить цвета каждой птицы в дамп json.Теперь я включаю BirdColorations в дамп, но мне все еще нужно разобраться с самими цветными моделями.Я мог бы отдельно включать цвета и окраски каждой птицы, а затем сопоставлять их при разборе, но я бы предпочел просто включить цвет каждой окраски напрямую.Что-то вроде

      format.json  { render :json => @birds.to_json(:include => [{:bird_colorations => :color}, :seasons, :habitats, :image_holders]) }

Выше не работает, однако.Я думаю, что это должно быть возможно.Кто-нибудь может указать мне правильное направление, как справиться с этим?

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

Спасибо!

Ответы [ 2 ]

51 голосов
/ 14 декабря 2010

Я нашел ответ здесь .Синтаксис для параметра: include в to_xml и to_json отличается от синтаксиса для метода find ActiveRecord.Чтобы включить вложенные ресурсы таким способом, вы передаете хеш вместо массива.Для меня правильный вызов метода выглядит следующим образом:

      format.json  { render :json => @birds.to_json(:include => {:bird_colorations => {:include => :color}, :seasons => {}, :habitats => {}, :image_holders => {}}) }

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

Живи и учись!

2 голосов
/ 14 декабря 2010

Если у вас сложная структура JSON, лучше переопределить serializable_hash или as_json в вашей модели, чем пытаться сделать все это через render :json.

Так что-то вроде

def serializable_hash(options = nil)
  options ||= {}
  bird = {:name => name, ...}
  bird[:seasons] = seasons.serilizable_hash
  bird[:colors] = ... # whatever complex logic you want to get to the colors
  bird
end

Обе функции просто должны возвращать хеш.

...