Search code examples
ruby-on-railsrubyruby-on-rails-3jsonruby-on-rails-3.1

How display selected Key of a serialized Hash?


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>

Solution

  • 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>