This project is archived and is in readonly mode.
value_changed? helper method
Reported by Jason Arora | March 17th, 2009 @ 11:21 PM | in 2.x
Added a new helper method to TextHelper called value_changed?, also includes test cases and documentation.
value_changed? tracks the value passed in and returns true whenever the value changes from its previous setting. It can be useful when iterating through a set of data that is organized in subsets to display a new title for each subset.
# Assuming people has been sorted by occupation...
<% @people.each do |person| %>
<%= "<h2>#{person.occupation.pluralize}</h2>" if value_changed?(person.occupation) %>
<%= person.name %><br/>
<% end %>
This produces:
<h2>Doctors</h2>
Jane Doe
John Smith
<h2>Programmers</h2>
Rails Rules
This little bit of code replaces the common pattern of:
<% previous_value = nil %>
<% @people.each do |person| %>
<% if previous_value != person.occupation %>
<% previous_value = person.occupation %>
<h2><%= person.occupation.pluralize %></h2>
<% end %>
<%= person.name %><br/>
<% end %>
Also, value_changed? accepts a name parameter to support nesting in loops (by default, the value is named "default").
I hope this is useful for others. It sure has been handy in my projects. Thanks!
Comments and changes to this ticket
-
Ian Terrell March 18th, 2009 @ 04:35 PM
Are there other use cases?
Do you see this as much better than using Enumerable#group_by? (http://api.rubyonrails.org/class...)
<% @people.group_by(&:occupation).each do |occupation, peeps| %> <h2><%= occupation %></h2> <% peeps.each do |person| %> <%= person.name %> <% end %> <% end %>
-
Jason Arora March 21st, 2009 @ 02:01 AM
Thanks for posting, Ian. You are correct, Enumerable#group_by is the best way to handle this pattern when ordering by a model attribute.
However, the value_changed? method works really well for dynamic cases, such as:
<% @people.each do |person| %> <%= "<h2>#{person.name.first}</h2>" if value_changed?(person.name.first) %> <%= person.name %><br/> <% end %> # => <h2>A</h2> # => Alan # => Amy # => <h2>B</h2> # => Barry # => ...
Is this more acceptable? Thanks again for the feedback.
Regards, Jason
-
Ian Terrell March 21st, 2009 @ 08:12 PM
For this use case, Enumerable#group_by still seems best. The &:symbol syntax is shorthand for a block; you can spell it out for cases where you wish to group by something that isn't a method:
<% @people.group_by{|person|person.name.first}.each do |initial, peeps| %> <h2><%= initial %></h2> <% peeps.each do |person| %> <%= person.name %> <% end %> <% end %>
-
Jeremy Kemper March 22nd, 2009 @ 01:42 AM
- State changed from new to wontfix
Nice patch, but agreed that group_by is a better choice for the problem it's solving
Create your profile
Help contribute to this project by taking a few moments to create your personal profile. Create your profile »
<h2 style="font-size: 14px">Tickets have moved to Github</h2>
The new ticket tracker is available at <a href="https://github.com/rails/rails/issues">https://github.com/rails/rails/issues</a>