nan*_*pus 35 json ruby-on-rails ruby-on-rails-3
我有一个模型,其中数据在呈现为json时永远不应包含在内.所以我实现了类'as_json方法以适当地运行.问题是当与此模型关联的其他模型呈现json时,我的自定义as_json未被调用.
class Owner < ActiveRecord::Base
has_one :dog
def as_json(options={})
puts "Owner::as_json"
super(options)
end
end
class Dog < ActiveRecord::Base
belongs_to :owner
def as_json(options={})
puts "Dog::as_json"
options[:except] = :secret
super(options)
end
end
Run Code Online (Sandbox Code Playgroud)
加载开发环境(Rails 3.0.3)
ruby-1.9.2-p136:001> d = Dog.first
=#<Dog id: 1, owner_id: 1, name: "Scooby", secret: "I enjoy crapping everwhere">>
ruby-1.9.2-p136:002> d.as_json
Dog :: as_json
=> {"dog" => {"id"=> 1,"name"=>"Scooby","owner_id"=> 1}}
ruby-1.9.2-p136:004> d.owner.as_json(:include =>:dog)
所有者:: as_json
=> {"owner"=> {"id"=> 1,"name"=>"Shaggy",:dog => {"id"=> 1,"name"=>"Scooby", "owner_id"=> 1,"秘密"=>"我喜欢疯狂到处"}}}}
谢谢您的帮助
如上所述,这是Rails基础的一个问题.轨道补丁这里还没有应用,似乎至少稍有争议,所以我犹豫本地应用它.即使应用为猴子补丁,也可能使未来的铁路升级变得复杂化.
我还在考虑上面建议的RABL,它看起来很有用.目前,我宁愿不在我的应用中添加另一种视图模板语言.我目前的需求非常小.
所以这是一个解决方法,它不需要补丁,适用于大多数简单的情况.这适用于as_json你想要调用的关联方法
def as_json(options={})
super( <... custom options ...> )
end
Run Code Online (Sandbox Code Playgroud)
在我的情况下,我有很多Schedule模型Events
class Event < ActiveRecord::Base
# define json options as constant, or you could return them from a method
EVENT_JSON_OPTS = { :include => { :locations => { :only => [:id], :methods => [:name] } } }
def as_json(options={})
super(EVENT_JSON_OPTS)
end
end
class Schedule < ActiveRecord::Base
has_many :events
def as_json(options={})
super(:include => { :events => { Event::EVENT_JSON_OPTS } })
end
end
Run Code Online (Sandbox Code Playgroud)
如果您遵循指南,只要您:include在as_json()方法中建立关联,就可以将所需的任何选项定义为要引用的模型中的常量,这适用于任意级别的关联.注意我只需要在上面的例子中定制的第一级关联.
我发现serializable_hash的工作原理与您期望的as_json一样,并且始终被称为:
def serializable_hash(options = {})
result = super(options)
result[:url] = "http://.."
result
end
Run Code Online (Sandbox Code Playgroud)