Как настроить ответ to_json в Rails 3 - PullRequest
16 голосов
/ 15 сентября 2010

Я использую respond_with и все правильно подключено для правильного получения данных. Я хочу настроить возвращенные форматы json, xml и foobar в СУХОЙ форме, но не могу понять, как это сделать, используя ограниченные значения :only и :include. Это замечательно, когда данные просты, но со сложными находками они не соответствуют тому, что я хочу.

Допустим, у меня есть сообщение, has_many изображения

def show
  @post = Post.find params[:id]
  respond_with(@post)
end

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

def show
  @post = Post.find params[:id]
  respond_with(@post, :include => :images)
end

но я действительно не хочу отправлять весь объект изображения, только URL. В дополнение к этому я действительно хочу иметь возможность делать что-то подобное (псевдокод):

def show
  @post = Post.find params[:id]
  respond_with(@post, :include => { :foo => @posts.each.really_cool_method } )
end

def index
  @post = Post.find params[:id]
  respond_with(@post, :include => { :foo => @post.really_cool_method } )
end

… но все СУХОЙ способ. В более старых проектах rails я использовал XML-компоновщики для настройки вывода, но реплицировал его через json, xml, html, что не кажется правильным. Я должен представить, что гуру рельсов поместили что-то в Rails 3, что я не понимаю для этого типа поведения. Идеи?

Ответы [ 3 ]

21 голосов
/ 26 января 2011

Вы можете переопределить as_json в вашей модели. Что-то вроде:

class Post < ActiveRecord::Base
  def as_json(options = {})
    {
      attribute: self.attribute, # and so on for all you want to include
      images:    self.images,    # then do the same `as_json` method for Image
      foo:       self.really_cool_method
    }
  end
end

А Rails позаботится об остальном при использовании respond_with. не совсем уверен, что для options установлено, но, вероятно, опции, которые вы даете respond_with (:include, :only и т. д.)

8 голосов
/ 09 февраля 2011

Возможно, слишком поздно, но я нашел более СУХОЕ решение, копающееся в документах по рельсам.Это работает в моих кратких тестах, но может потребовать некоторой настройки:

# This method overrides the default by forcing an :only option to be limited to entries in our
# PUBLIC_FIELDS list
def serializable_hash(options = nil)
  options ||= {}
  options[:only] ||= []
  options[:only] += PUBLIC_FIELDS
  options[:only].uniq!
  super(options)
end

Это в основном позволяет вам иметь список полей, разрешенных для вашего публичного API, и вы не можете случайно выставить весь объект.Вы по-прежнему можете открывать определенные поля вручную, но по умолчанию ваш объект защищен для .to_json, .to_xml и т. Д.

7 голосов
/ 17 сентября 2010

Это не встроенный в rails 3 способ, но я нашел большой драгоценный камень, который активно поддерживается в Rails 3: acts_as_api

...