Peege151
Peege151

Reputation: 1560

Displaying Key, Value in Selection Field in Rails

I have created a hash with key(name of shipping type) and value(price of shipping_type):

<% ship_hash = {} %>
   <% @order_preview.fedex_rates.each do |rate| %>
        <% if rate.service_name == "FedEx Ground Home Delivery" || rate.service_name == "FedEx 2 Day" || rate.service_name == "FedEx Standard Overnight" %>
        <%= ship_hash["#{rate.service_name}"] = ["#{number_to_currency(rate.price.to_f / 100)}"] %>
        <% end %>
    <% end %>
   <% @order_preview.usps_rates.each do |rate| %>
        <% if rate.service_name == "USPS Priority Mail 1-Day" %>
          <%= ship_hash["#{rate.service_name}"] = ["#{number_to_currency(rate.price.to_f / 100)}"] %>
        <% end %>
    <% end %>

I want to update a form so a user can see the the shipping_type and shipping_price the select field.

I have this so far

<%= f.select(:shipping_type, ship_hash.map {|k, v| [k, v]}) %>

but that gives me enter image description here and when clicked it looks lke this....

enter image description here

I want it all in one line, with the Shipping_type name, followed by the price. Is this possible?

Thanks

Sorry if this is easy but I didn't see it.

Thanks, Pat

Upvotes: 0

Views: 102

Answers (2)

Himesh
Himesh

Reputation: 646

First thing - Avoid declaring/initializing variables on views. This is not as per convention

Add a helper method to retrieve the options

in helper

def ship_options(ship_hash)
  ship_options = []
  ship_hash.each do |k , v|
    ship_options << ["#{k} - #{v}", v]
  end
  ship_options
end

on view

<%= f.select(:shipping_type, ship_options(ship_hash) %>

Upvotes: 1

user740584
user740584

Reputation:

I think the problem is you are building ship_hash with the value as an array rather than just a string. When this goes into the select helper it's effectively creating you a grouped_options_for_select rather than just a plain options_for_select.

I'm assuming you would want to display your select list something like:

FedEx Ground Home Delivery - $9.78
FedEx 2 Day - $20.59
FedEx Standard Overnight - $33.78
USPS Priority Mail 1-Day - $5.60

and the value returned after the user selects will be one of FedEx Ground Home Delivery, FedEx 2 Day, FedEx Standard Overnight, USPS Priority Mail 1-Day - i.e. the service_name.

To do this, you could build the list of shipping options in the controller. Something like:

@ship_hash = {}
@order_preview.fedex_rates.each do |rate|
  if ['FedEx Ground Home Delivery', 'FedEx 2 Day', 'FedEx Standard Overnight'].include?(rate.service_name)
    @ship_hash.merge!(rate.service_name => "#{view_context.number_to_currency(rate.price.to_f / 100)")
  end
end
@order_preview.usps_rates.each do |rate|
  if ['USPS Priority Mail 1-Day'].include?(rate.service_name)  # array include? structure for when you want to increase the available options later
    @ship_hash.merge!(rate.service_name => "#{view_context.number_to_currency(rate.price.to_f / 100)")
  end
end
# Note: I'm using view_context.number_to_currency to get access to the helper method in    
#       the controller; this keeps it simple and I don't want to get into the debate of 
#       using helpers in controllers here as it's not directly relevant to this question :-)

And then use them something like:

<%= f.select(:shipping_type, options_for_select(@ship_hash.map { |k,v| ["#{k} - #{v}",k] })) %>

This should build you a simple selector with a single line per shipping option, but showing you both the service name and rate on each line:

<select id="yourmodel_shipping_type" name="yourmodel[shipping_type]">
  <option value="FedEx Ground Home Delivery">FedEx Ground Home Delivery - $9.78</option>
  <option value="FedEx 2 Day">FedEx 2 Day - $20.59</option>
  <option value="FedEx Standard Overnight">FedEx Standard Overnight - $33.78</option>
  <option value="USPS Priority Mail 1-Day">USPS Priority Mail 1-Day - $5.60</option>
</select> 

Upvotes: 0

Related Questions