I have a serialized hash of a checkbox, and i would like to display just the selected keys.
Model
class Policy < ActiveRecord::Base
belongs_to :user
serialize :shipping, JSON
end
View
<ul>
<%= p.fields_for :shipping, @policy.shipping do |s|%>
<li><%= s.check_box :fedex %><%= s.label :fedex %></li>
<li><%= s.check_box :dhl %><%= s.label :dhl %></li>
<li><%= s.check_box :usps_10 %><%= s.label :usps %></li>
</ul>
<% end %>
BD
{"fedex":"1","usps":"0","dhl":"0"}
View Show
<ul>
<% if [email protected]? %>
<% @policy.shipping.keys.each do |key|%>
<li><%= key %></li>
<% end %>
<% end %>
</ul>
Your @policy.shipping
should be a plain old Hash so select
should sort you out:
<ul>
<% if @policy.shipping.present? %>
<% @policy.shipping.select { |k, v| v == 1 }.keys.each do |key| %>
<li><%= key %></li>
<% end %>
<% end %>
</ul>
I'm not sure off the top of my head if you'll get 1
or '1'
in your values though so you might need to v == '1'
inside the select
block.
You can skip the .present?
(or !...nil?
) check by taking advantage of the fact that nil.to_a
is []
as well:
<ul>
<% @policy.shipping.to_a.select { |k, v| v == 1 }.map(&:first).each do |key| %>
<li><%= key %></li>
<% end %>
</ul>
Or even:
<ul>
<% @policy.shipping.to_a.select { |k, v| v == 1 }.each do |a| %>
<li><%= a.first %></li>
<% end %>
</ul>
And you probably want to fix your original view to be properly nested or you might run into strange things in the future:
<ul>
<%= p.fields_for :shipping, @policy.shipping do |s|%>
<li><%= s.check_box :fedex %><%= s.label :fedex %></li>
<li><%= s.check_box :dhl %><%= s.label :dhl %></li>
<li><%= s.check_box :usps_10 %><%= s.label :usps %></li>
<% end %>
</ul>