Подтвердить что ты не робот

Ruby on Rails Advanced JSON Serialization

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

Вот мой контроллер сейчас:

if params[:id]
    @article = Article.find(params[:id])
else
    @article = Article.published.not_draft.by_recent.first
end

respond_to do |format|

format.js { render :json => @article.to_json(
:except => [ :created_at, :updated_at, :draft, :id, :publish ], 
:include => {
    :comments => {
        :only => [:body]
    }
}),
:callback => params[:callback]}
end

Что бы я хотел сделать в ответ, добавьте индекс всех статей, например:

@index = Article.find(:all, :select => 'id, title')

Единственный способ, которым я смог это сделать, - поместить индекс и статью в хэш или массив, а затем поместить это в JSON.

@response = { :item => @article, :index => @index }

Полный код с обоими:

@index = Article.find(:all, :select => 'id, title')

if params[:id]
    @article = Article.find(params[:id])
else
    @article = Article.published.not_draft.by_recent.first
end

@response = { :item => @article, :index => @index }

respond_to do |format|

format.js { render :json => @response.to_json(), :callback => params[:callback]}

end

Это было бы хорошо, но теперь я не могу указать :include или :except и получить его для правильного отображения.

4b9b3361

Ответ 1

Вы намекаете на решение в своем вопросе. Скорее всего, вы хотите создать хэш для рендеринга JSON. Предпочтительный способ сделать это сейчас - обеспечить реализацию метода as_json. as_json предоставляет формальные средства настройки вывода to_json путем создания хэша, содержащего данные, которые вы хотите кодировать.

Более тщательное рассмотрение того, как взаимодействовать as_json и to_json, можно найти на веб-сайте Джонатана Джулиана.

Ответ 2

Просто, чтобы быть понятным, код выше работает с: include и: except. И по работам я имею в виду, что это не вызывает ошибки. Проблема состоит в том, что он включает комментарии для каждой статьи в индексе. Я просто хочу включить комментарии для: item, а не из статей, перечисленных в индексе.

Я не мог заставить вложенность работать как хэш или объект OpenStruct.

Вложение включено: включает в себя ошибку, вложенность: исключение не выдает ошибку, но ничего не отфильтровывается: created_at и т.д. все еще отображаются.

...

@response = { :item => @article, :index => @index }

format.js { render :json => @response.to_json(
:except => {:item => [ :created_at, :updated_at, :draft, :id, :publish ]}, 
:include => { :item => {
        :comments => {
                :only => [:body]
        }
}}),
:callback => params[:callback]}
end

Ответ 3

Вы должны иметь возможность вставлять :include, :except и т.д. так:

:except => {:item => [ :created_at, :updated_at, :draft, :id, :publish ]}...

Если это не работает, сделайте его объектом (например, OpenStruct) вместо хеша.

- Маркус

Ответ 4

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

Ответ 5

(Примите ответ)

Я думаю, что ссылка, которую дал нирвдрум, содержит ваш ответ. Я отвечаю только потому, что никто не упомянул encode_json.

В вашем случае вы должны иметь дело только с as_json. Либо создавая хеш (с различными вызовами as_json), и отправляя его на render :json => ... (без вызова to_json), либо просто реализуя as_json на вашей модели и позволяя рельсам выполнять всю работу. (Но я подозреваю, что вам понадобится первая.)

Если вам действительно нужны какие-то причудливые js в вашем рендерированном ответе, вы можете реализовать encode_json в своих классах (опять же, не to_json). Например:

class JsEmptyClosure
  def encode_json(*args)
    "jQuery[\"noop\"] || function(){}"
  end
  def as_json(*args) self end
end

Теперь ответ будет отвечать to_json на допустимые js (но обратите внимание, что это не json).

Ответ 6

Спасибо за вопрос, я могу настроить свой json-формат для модели с несколькими ассоциациями.

сделать json: @posts.to_json (

: except = > [: created_at,: updated_at,: user_id],

: include = > {

: user = > {: only = > [: email,: phone]},

: location = > {: only = > [: title,: lat,: lon,: street,: city,: state,: Почтовый индекс]},

: uploads = > {: only = > [: image]}

}
)

Ответ 7

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

class Article
   def attributes
     { ... } # define your hash that you want to return at the '...'
   end
end

Мне кажется, что это намного проще, чем прямо с to_json.