Posted almost 9 years ago. Visible to the public.

Virtual attributes for array fields

When a has_many association basically serves to store a list of associated strings (tags, categories, …), it can be convenient to represent this association as a string array in the containing model. Here is an example for this pattern from the acts-as-taggable-on gem:

Copy
post = Post.last p post.tag_list # ['foo', 'bar', 'baz'] post.tag_list = ['bam'] p post.tag_list # ['bam']

This string array tag_list is magical in several ways:

  • It is read from and written to a has_many association
  • It can be manipulated in forms using a single text_field. Multiple elements will be separated with commas.
  • In order to change its elements, it can be assigned both an array of strings or a comma-separated string
  • It survives form roundtrips in case of validation errors as expected. ActiveRecord has this horrible API where changes to associations are written to the database immediately after calling the setter. Just like regular, flat attributes they will be converted to their underlying associations only if the record is valid and could be saved.

Use the attached Modularity below to add such a magical array to your model. Besides using the trait, you will need to implement two methods to synchronize the string array with its underlying association:

Copy
class Note < ActiveRecord::Base include DoesListField[:topic_list] private def read_topic_list topics.collect(&:name) end def write_topic_list(list) topics.delete_all for name in list topics.create!(:name => name) end end end

In case your list holds integer values, you might want to use the :integer option so elements get casted to numbers automagically:

Copy
class Note < ActiveRecord::Base include DoesListField[:author_list, integer: true] end
Growing Rails Applications in Practice
Check out our new e-book:
Learn to structure large Ruby on Rails codebases with the tools you already know and love.

Owner of this card:

Avatar
Henning Koch
Last edit:
over 3 years ago
by Henning Koch
Attachments:
does_list_field.rb
About this deck:
We are makandra and do test-driven, agile Ruby on Rails software development.
License for source code
Posted by Henning Koch to makandra dev
This website uses cookies to improve usability and analyze traffic.
Accept or learn more