2011-03-26 3 views
2

Я ищу, чтобы вернуть некоторые данные для запроса json в рельсах, и мне было интересно, не искажены ли данные. Вот сокращенный пример:Malformed Rails JSON и jQuery

[{"company":{"name":"A"}},{"company":{"name":"B"}}] 

Я всегда считал, что при возвращении JSON он должен описать корневой элемент и множественные, поэтому она должна вернуть что-то подобное:

{"companies":[{"name":"A"},{"name":"B"}]} 

Вот вопросы - это каким-то образом я могу заставить моего json выйти в таком формате? Это даже правильный формат или каждый узел компании должен быть помечен также? Нужно ли создавать собственное представление для получения моих результатов? Каков наилучший способ заставить jQuery зацикливать данные в текущем формате? Сейчас я использую:

format.json { render :json => @companies.to_json() } 

Чтобы сделать результаты.

Заранее благодарим за помощь/совет.

+0

Все еще неясно - единственный способ для Rails создать второй пример для создания пользовательского представления? (Это для индексного представления) – sshefer

ответ

4

Возможно, вы ищете что-то вроде JSend specification. Я придумал это сам, прежде чем понял, что это было сделано раньше, потому что я нашел чрезвычайно полезным иметь стандартный контейнер ответов для служб JSON.

Вот как я бы переписать ответ сервера:

format.json do 
    render :json => { 
    :status => 'success', 
    :data => { 
     :companies => @companies 
    } 
    } 
end 

Есть моменты, когда вам нужно изменить атрибуты, которые генерируются при преобразовании в JSON. В таких случаях я просто использовать map:

format.json do 
    render :json => { 
    :status => 'success', 
    :data => { 
     :companies => @companies.map do |company| 
     hash = company.attributes 
     hash['address'] = company.address 
     hash.delete('secret') 
     hash 
     end 
    } 
    } 
end 

Чуть более многословен, чем to_json, но это более гибкая и работает так же хорошо в стойку ППО.

+0

Сохраняет ключ «компании» для каждого объекта. Также кажется, что если я просто использую «@companies», я теряю специфику, которую я получаю с помощью метода to_json, нет? – sshefer

+0

@sshefer Вы можете удалить ключ компании, установив в инициализаторе 'ActiveRecord :: Base.include_root_in_json = false'. Если мне нужно изменить атрибуты, я просто использую вместо этого 'map'. –

+0

Спасибо Адаму - я фактически закончил использование «as_json» в своей модели, чтобы определить, как должен выглядеть ответ json по умолчанию, а затем отправить некоторые дополнительные параметры по мере необходимости. Этот ответ был самым близким к тому, что я искал! – sshefer

1

Оба действительны JSON. Однако я согласился бы с вами, что второй предпочтительнее. Он менее избыточный, поскольку первый имеет ненужный слой объекта и повторяет ключ компании. Но более тонким преимуществом является то, что второй защищает вас от JSON hijacking, что возможно только тогда, когда корневая структура является массивом.

Чтобы зацикливать первый, используйте, например,

$.getJSON(url, functon(resp) 
{ 
    for(var i = 0; i < resp.length; i++) 
    { 
    var company = resp[i].company; 
    var name = company.name; 
    } 
}); 
+0

должно быть resp [i] – wildcard

+0

Спасибо, @wildcard, исправлено. –

Смежные вопросы