Devise的舊版本(< 1.4.2)在to_json和to_xml方法上執行monkeypatch,並使用attr_accessible中定義的屬性覆蓋:only => []選項。煩人。
現在已經改變了,所以serializable_hash會被覆蓋,而to_json或to_xml中設置的任何:only => [:attribute]選項都會被保留。
在我的情況下,我最終完成了自己的to_json腳本,併爲所有ActiveRecord模型添加了一個方法api_accessible。
class ActiveRecord::Base
def to_json(options = {}, &block)
if self.class.respond_to?(:api_attributes)
super(build_serialize_options(options), &block)
else
super(options, &block)
end
end
class << self
attr_reader :api_attributes
def api_accessible(*args)
@api_attributes ||= []
@api_attributes += args
end
end
private
def build_serialize_options(options)
return options if self.class.api_attributes.blank?
methods = self.class.instance_methods - self.class.attribute_names.map(&:to_sym)
api_methods = self.class.api_attributes.select { |m| methods.include?(m) }
api_attrs = self.class.api_attributes - api_methods
options.merge!(only: api_attrs) if api_attrs.present?
options.merge!(methods: api_methods) if api_methods.present?
return options
end
end
這意味着您現在可以定義調用to_json時將默認公開的屬性列表(和方法!)。 Respond_with也使用to_json,所以它對API很好。
例如,user.rb
class User < ActiveRecord::Base
devise :database_authenticatable, :registerable, :confirmable,
:recoverable, :rememberable, :trackable, :validatable
#Setup accessible (or protected) attributes for your model
attr_accessible :email,
:password,
:password_confirmation,
:remember_me,
:first_name,
:last_name,
api_accessible :id,
:name,
:created_at,
:first_name,
:last_name,
:some_model_method_also_works
end
感謝。真的很煩人,他們沒有提供一種關閉這種行爲的方式。 這是非常荒謬的假設attr_accessible是說「我想公開這些,只有這些屬性在我的API」 – tomblomfield