Ответ 1
Это не рельсы 3 встроенный, но я нашел большой камень, который активно поддерживается на Rails 3: acts_as_api
Я использую 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, что я не понимаю этого поведения. Идеи?
Это не рельсы 3 встроенный, но я нашел большой камень, который активно поддерживается на Rails 3: acts_as_api
Вы можете переопределить 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
и т.д.)
Возможно, слишком поздно, но я нашел более 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 и т.д.