I have a line like this:
<%= f.input :state_id, :input_html => {:value => (policy_address.state.name rescue nil)}, :required => true, :collection => states.map {|s| [ s.name, s.id] }, :include_blank => 'Please select'%>
I want to exclude a value from the states.map collection. I thought that this would work but it doesn't:
<%= f.input :state_id, :input_html => {:value => (policy_address.state.name rescue nil)}, :required => true, :collection => states.map {|s| [ s.name, s.id] unless s.name == "excluded_state" }, :include_blank => 'Please select'%>
I put in unless s.name == "excluded_state, but, again, it's not working:
What am I doing wrong?
map doesn't allow to skip values. You have to reject unwanted elements first.
states.reject { |s| s.name == "excluded_state" }.map { |s| [s.name, s.id] }
Another (dirtier) solution is to return nil for excluded elements and use Array#compact on the resulting array to remove those nil elements:
states.map { |s| s.name == "excluded_state" ? nil : [s.name, s.id] }.compact
                        Eureka's answer is good but here is just a brief explanation to clarify what's going on.
map returns a new array with the results of running block once for every element in the array. When you write [s.name, s.id] unless s.name == "excluded_state" this causes the block to return nil when s.name == "excluded_state" i.e. the result would be something like
[["NY", 1], nil, ["CA", 2]]
So you could use reject to remove the unwanted state first, or you could just use compact1 to remove the nil entry on the result of your map as you originally wrote it. 
Array#compact returns a copy of the array with all nil elements removed.If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With