Отфильтруйте атрибуты модели перед выводом как json - PullRequest
3 голосов
/ 29 декабря 2010

Эй, ребята, мне нужно вывести мою модель как json, и все идет хорошо. Однако некоторые атрибуты необходимо «украсить», отфильтровав их через некоторые вспомогательные методы, такие как number_to_human_size. Как бы я поступил так?

Другими словами, скажите, что у меня есть атрибут с именем bytes, и я хочу передать его через number_to_human_size и иметь , чтобы результат был выведен в json.

Я также хотел бы «обрезать» то, что выводится как json, если это возможно, поскольку мне нужны только некоторые атрибуты. Это возможно? Может кто-нибудь дать мне пример? Я был бы очень признателен.

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

Исследования : Кажется, я могу использовать опции to_json, чтобы явно указать, какие атрибуты мне нужны, но мне все еще нужно выяснить, как "украсить" или "отфильтровать" определенные атрибуты, передавая их через помощника, прежде чем они выводятся как json.

Могу ли я создать партиал для одной модели json, поэтому _model.json.erb, а затем создать еще один для действия, которое я использую, и в рамках этого просто визуализировать партиал с коллекцией объектов? Похоже на кучу обручей, через которые можно прыгнуть. Мне интересно, есть ли более прямой / грубый способ изменить представление модели в json.

Ответы [ 2 ]

7 голосов
/ 29 декабря 2010

Ваша модель может переопределить метод as_json, который Rails использует при рендеринге json:

# class.rb
include ActionView::Helpers::NumberHelper
class Item < ActiveRecord::Base
  def as_json(options={})
    { :state => state, # just use the attribute when no helper is needed
      :downloaded => number_to_human_size(downloaded)
    }
  end
end

Теперь вы можете позвонить render :json в контроллере:

@items = Item.all
# ... etc ...
format.json { render :json => @items }

Rails вызовет Item.as_json для каждого члена @items и вернет JSON-кодированный массив.

1 голос
/ 29 декабря 2010

Я выяснил a решение этой проблемы, но я не знаю, является ли оно лучшим.Я был бы признателен за понимание.

@items = Item.all

@response = []

@items.each do |item|
  @response << {
      :state => item.state,
      :lock_status => item.lock_status,
      :downloaded => ActionController::Base.helpers.number_to_human_size(item.downloaded),
      :uploaded => ActionController::Base.helpers.number_to_human_size(item.uploaded),
      :percent_complete => item.percent_complete,
      :down_rate => ActionController::Base.helpers.number_to_human_size(item.down_rate),
      :up_rate => ActionController::Base.helpers.number_to_human_size(item.up_rate),
      :eta => item.eta
  }
end

respond_to do |format|
  format.json { render :json => @response }
end

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

...