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

Как настроить ответ to_json в Rails 3

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

Допустим, у меня есть сообщение, в котором has_many images

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

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

4b9b3361

Ответ 1

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

Ответ 2

Вы можете переопределить 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 и т.д.)

Ответ 3

Возможно, слишком поздно, но я нашел более DRY-решение, копающееся через рельсы docs. Это работает в моих кратких тестах, но может потребоваться некоторые настройки:

# 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 и т.д.