Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support optional types for computed attributes #170

Merged
merged 2 commits into from Mar 8, 2013
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
14 changes: 14 additions & 0 deletions README.md
Expand Up @@ -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:

Expand Down
12 changes: 9 additions & 3 deletions lib/active_model/serializer.rb
Expand Up @@ -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})
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oof, that is a busy line if code.


attr = attr.keys[0] if attr.is_a? Hash

unless method_defined?(attr)
define_method attr do
Expand Down Expand Up @@ -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

Expand Down
7 changes: 4 additions & 3 deletions test/serializer_test.rb
Expand Up @@ -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,
Expand Down Expand Up @@ -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 => [{
Expand Down