MBO/attrtastic — Issue #16: Better support for ActiveRecord associations
Author: itspriddle
Created: 2012-03-09 19:16:30+00:00
State: open

I've been working on adding better support to attrtastic for attributes that are ActiveRecord associations. Currently, attrtastic just calls `.to_s` on them, and you end up with something like `#`.

Here are the relevant pieces of an app to illustrate what I'm talking about.

Given the following models/associations:

```ruby
# app/models/author.rb
# Attributes: :id, :name
class Author < ActiveRecord::Base
has_many :posts
end

# app/models/post.rb
# Attributes: :id, :name
class Post < ActiveRecord::Base
belongs_to :author
end

# Created as:
author = Author.create! name: "Josh"
post = Post.create! name: "First Post", author_id: author.id
```

and given this ERB:

```erb
# app/views/posts/show.html.erb
<%= semantic_attributes_for @post do |attr| %>
<%= attr.attributes do %>
<%= attr.attribute :name %>
<%= attr.attribute :author %>
<% end %>
<% end %>
```

My changes would generate this HTML:

```html

NameFirst Post

AuthorJosh

```

Here's the code that provides this behavior:

```ruby
Attrtastic.default_options.merge!(
# If an attribute is an ActiveRecord itself, check for any of these columns
# to print it's value. Otherwise, fallback to .to_s
active_record_name_columns: [:full_name, :name, :title]
)

module Attrtastic
class SemanticAttributesBuilder
def format_attribute_value_custom(value)
opts = Attrtastic.default_options.fetch(:active_record_name_columns, [:name])
case value
when ActiveRecord::Base
if meth = opts.find { |m| value.respond_to?(m) }
value.send(meth).to_s
else
"#{value.class.name.humanize} ##{value.id}"
end
else
format_attribute_value_default value
end
end
alias_method :format_attribute_value_default, :format_attribute_value
alias_method :format_attribute_value, :format_attribute_value_custom
end
end
```

If that's something you think might be useful for other users, I'd be happy to clean it up and submit a proper patch.