diff --git a/README.md b/README.md index 2d70c71ad..d44f9d25a 100644 --- a/README.md +++ b/README.md @@ -232,6 +232,20 @@ class PostSerializer < ActiveModel::Serializer end ``` +The type of a computed attribute (like :full_name above) is not easily +calculated without some sophisticated static code analysis. To specify the +type of a computed attribute: + +```ruby +class PersonSerializer < ActiveModel::Serializer + attributes :first_name, :last_name, {:full_name => :string} + + def full_name + "#{object.first_name} #{object.last_name}" + end +end +``` + If you would like the key in the outputted JSON to be different from its name in ActiveRecord, you can use the `:key` option to customize it: diff --git a/lib/active_model/serializer.rb b/lib/active_model/serializer.rb index 06deb23b3..8cc8b9909 100644 --- a/lib/active_model/serializer.rb +++ b/lib/active_model/serializer.rb @@ -73,7 +73,9 @@ def attributes(*attrs) end def attribute(attr, options={}) - self._attributes = _attributes.merge(attr => options[:key] || attr.to_s.gsub(/\?$/, '').to_sym) + self._attributes = _attributes.merge(attr.is_a?(Hash) ? attr : {attr => options[:key] || attr.to_s.gsub(/\?$/, '').to_sym}) + + attr = attr.keys[0] if attr.is_a? Hash unless method_defined?(attr) define_method attr do @@ -175,8 +177,12 @@ def schema attrs[key] = column.type else # Computed attribute (method on serializer or model). We cannot - # infer the type, so we put nil. - attrs[key] = nil + # infer the type, so we put nil, unless specified in the attribute declaration + if name != key + attrs[name] = key + else + attrs[key] = nil + end end end diff --git a/test/serializer_test.rb b/test/serializer_test.rb index 185b7c433..389e27723 100644 --- a/test/serializer_test.rb +++ b/test/serializer_test.rb @@ -491,16 +491,17 @@ class << self; self; end.class_eval do # Computed attributes (not real columns or associations). def can_edit; end + def can_view; end def drafts; end - attributes :name, :age, :can_edit + attributes :name, :age, {:can_edit => :boolean}, :can_view has_many :posts, :serializer => Class.new has_many :drafts, :serializer => Class.new has_one :parent, :serializer => Class.new end assert_equal serializer.schema, { - :attributes => { :name => :string, :age => :integer, :can_edit => nil }, + :attributes => { :name => :string, :age => :integer, :can_edit => :boolean, :can_view => nil }, :associations => { :posts => { :has_many => :posts }, :drafts => nil, @@ -1004,7 +1005,7 @@ def self.to_s :name => 'logo.png', :url => 'http://example.com/logo.png', :attachable => { - :type => :email, + :type => :email, :id => 1 }}, :emails => [{