Skip to content
This repository was archived by the owner on Jan 2, 2020. It is now read-only.
This repository was archived by the owner on Jan 2, 2020. It is now read-only.

Better support for ActiveRecord associations #16

@itspriddle

Description

@itspriddle

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 #<Post:0x007f893f477a78>.

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

Given the following models/associations:

# 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:

# 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:

<div class="attrtastic post">
  <div class="attributes"><ol>
    <li class="attribute"><span class="label">Name</span><span class="value">First Post</span></li>
    <li class="attribute"><span class="label">Author</span><span class="value">Josh</span></li>
</ol></div></div>

Here's the code that provides this behavior:

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions