title: Rails: dynamic select on multistep form not keeping selected
body: <p>I am working on a multistep form for an order placement process following Ryan Bates's <a href="http://railscasts.com/episodes/217-multistep-forms?view=asciicast" rel="nofollow noreferrer">Multistep Tutorial #217</a> which uses a session. On the first step I have two select fields: one for countries (land) and a dynamic one for shipping services. After a land has been selected the shipping services are loaded into the second select field through javascript/jQuery and the total price is calculated through JS.</p>
  
  <p>app/views/orders/_shipping_step.html.erb</p>
  
  <pre><code>&lt;%= f.collection_select(:land_id, Land.all, :id, :name, {:prompt =&gt; "select a country"}, {:id =&gt; 'lands_select'}) %&gt;
  &lt;%= f.select(:shippingservice_id, options_for_select(@shippingservices.collect { |s| [s.name.titleize, s.id, {'data-price' =&gt; s.price}] }, :selected =&gt; f.object.shippingservice_id), {:prompt =&gt; "select a carrier"}, {:id =&gt; "shippingservices_select"}) %&gt;
  </code></pre>
  
  <p>ajax script</p>
  
  <pre><code>$(document).on("change", "#lands_select", function(event){
    $.ajax({
      url: "/carts/update_shipping/" + event.target.value,
      type: "GET",
    })
  });
  </code></pre>
  
  <p>On the shipping details step of the multistep form I can choose a land, the corresponding options for shipment are loaded and I can choose one. When progressing to the payment step, I can place the order and everything works, but in case I want to return from the payment step to the order step to change something, the shipping services selector displays options for land_id = 1, while the land select displays the choose country, for example id 85.</p>
  
  <p>I added <code>:selected =&gt; session[:cart_params]</code> to the shipping service select, but it does not appear to be working. <code>:selected =&gt; f.object.shippingservice_id</code> keeps priority or standard shipping options, but for Land_id 1.</p>
  
  <p>How can I get this working? Is it the select field or the JS? Why doesn't the second select keep the chosen land in memory?</p>
  
  <p>Thank you in advance!</p>
  
  <p>LOG:</p>
  
  <pre><code>Started GET "/orders/new" for 127.0.0.1 at Thu Dec 27 22:08:52 +0100 2018
  Processing by OrdersController#new as HTML
    Cart Load (0.3ms)  SELECT `carts`.* FROM `carts` WHERE `carts`.`id` = ? LIMIT 1  [["id", 1]]
    Land Load (1.4ms)  SELECT `lands`.* FROM `lands` 
    CartItem Load (0.3ms)  SELECT `cart_items`.* FROM `cart_items` WHERE `cart_items`.`cart_id` = 1
     (0.2ms)  SELECT MAX(`cart_items`.`length`) AS max_id FROM `cart_items` WHERE `cart_items`.`cart_id` = 1
     (0.2ms)  SELECT MAX(`cart_items`.`width`) AS max_id FROM `cart_items` WHERE `cart_items`.`cart_id` = 1
    CACHE (0.0ms)  SELECT `lands`.* FROM `lands` 
    Shippingservice Load (0.6ms)  SELECT `shippingservices`.* FROM `shippingservices` INNER JOIN `zones` ON `zones`.`id` = `shippingservices`.`zone_id` INNER JOIN `lands_zones` ON `lands_zones`.`zone_id` = `zones`.`id` INNER JOIN `lands` ON `lands`.`id` = `lands_zones`.`land_id` WHERE `lands`.`id` = 1 AND (weightmin &lt;= 50 AND weightmax &gt;= 50 AND heightmin &lt;= 3 AND heightmax &gt;= 3 AND shippingservices.shippingcarrier = ‘1’) AND (lengthmax &gt;= 210 AND widthmax &gt;= 149)
    Product Load (0.3ms)  SELECT `products`.* FROM `products` WHERE `products`.`id` = 3 LIMIT 1
    Hero Load (0.2ms)  SELECT `heros`.* FROM `heros` WHERE `heros`.`id` = 18 LIMIT 1
    Rendered orders/_shipping_step.html.erb (13.7ms)
    Rendered orders/new.html.erb within layouts/application (16.2ms)
    Rendered layouts/_header.html.erb (0.1ms)
    Rendered layouts/_footer.html.erb (0.1ms)
  Completed 200 OK in 44ms (Views: 23.0ms | ActiveRecord: 3.9ms)
  </code></pre>
  
  <p>Selecting the shipping country:</p>
  
  <pre><code>Started GET "/carts/update_shipping/85" for 127.0.0.1 at Thu Dec 27 22:09:27 +0100 2018
  Processing by CartsController#update_shipping as */*
    Parameters: {"id"=&gt;"85"}
    Cart Load (0.2ms)  SELECT `carts`.* FROM `carts` WHERE `carts`.`id` = ? LIMIT 1  [["id", 1]]
    Land Load (66.9ms)  SELECT `lands`.* FROM `lands` 
    CartItem Load (0.4ms)  SELECT `cart_items`.* FROM `cart_items` WHERE `cart_items`.`cart_id` = 1
     (0.2ms)  SELECT MAX(`cart_items`.`length`) AS max_id FROM `cart_items` WHERE `cart_items`.`cart_id` = 1
     (0.2ms)  SELECT MAX(`cart_items`.`width`) AS max_id FROM `cart_items` WHERE `cart_items`.`cart_id` = 1
    Shippingservice Load (0.6ms)  SELECT `shippingservices`.* FROM `shippingservices` INNER JOIN `zones` ON `zones`.`id` = `shippingservices`.`zone_id` INNER JOIN `lands_zones` ON `lands_zones`.`zone_id` = `zones`.`id` INNER JOIN `lands` ON `lands`.`id` = `lands_zones`.`land_id` WHERE `lands`.`id` = 85 AND (weightmin &lt;= 50 AND weightmax &gt;= 50 AND heightmin &lt;= 3 AND heightmax &gt;= 3 AND shippingservices.shippingcarrier = ‘1’) AND (lengthmax &gt;= 210 AND widthmax &gt;= 149)
    Rendered carts/_shippingservice.html.erb (0.2ms)
    Rendered carts/update_shipping.js.erb (2.9ms)
  Completed 200 OK in 87ms (Views: 7.8ms | ActiveRecord: 68.6ms)
  </code></pre>
  
  <p>Progressing to the next step:</p>
  
  <pre><code>Started POST "/orders" for 127.0.0.1 at Thu Dec 27 22:09:33 +0100 2018
  Processing by OrdersController#create as HTML
    Parameters: {"order"=&gt;{"ship_to_last_name"=&gt;”surname”, "ship_to_address"=&gt;”street”, "ship_to_city"=&gt;”city”, "ship_to_postal_code"=&gt;”postcode”, "phone_number"=&gt;”somenumber”, "shippingservice_id"=&gt;"27", "email"=&gt;”something@example.tld”, "land_id"=&gt;"85", "ship_to_first_name"=&gt;”firstname”}, "authenticity_token"=&gt;”somestring”, "utf8"=&gt;"✓", "commit"=&gt;"Continue"}
    Cart Load (0.2ms)  SELECT `carts`.* FROM `carts` WHERE `carts`.`id` = ? LIMIT 1  [["id", 1]]
    Land Load (1.5ms)  SELECT `lands`.* FROM `lands` 
    CartItem Load (0.4ms)  SELECT `cart_items`.* FROM `cart_items` WHERE `cart_items`.`cart_id` = 1
     (0.2ms)  SELECT MAX(`cart_items`.`length`) AS max_id FROM `cart_items` WHERE `cart_items`.`cart_id` = 1
     (0.2ms)  SELECT MAX(`cart_items`.`width`) AS max_id FROM `cart_items` WHERE `cart_items`.`cart_id` = 1
    Land Load (0.4ms)  SELECT `lands`.* FROM `lands` WHERE `lands`.`id` = 85 LIMIT 1
    Shippingservice Load (0.3ms)  SELECT `shippingservices`.* FROM `shippingservices` WHERE `shippingservices`.`id` = 27 LIMIT 1
    Product Load (0.3ms)  SELECT `products`.* FROM `products` WHERE `products`.`id` = 3 LIMIT 1
    Hero Load (0.3ms)  SELECT `heros`.* FROM `heros` WHERE `heros`.`id` = 18 LIMIT 1
    Rendered orders/_payment_step.html.erb (7.0ms)
    Rendered orders/new.html.erb within layouts/application (8.9ms)
    Rendered layouts/_header.html.erb (0.1ms)
    Rendered layouts/_footer.html.erb (0.0ms)
  Completed 200 OK in 39ms (Views: 13.7ms | ActiveRecord: 4.6ms)
  </code></pre>
  
  <p>Returning to the shipping details step:</p>
  
  <pre><code>Started POST "/orders" for 127.0.0.1 at Thu Dec 27 22:09:35 +0100 2018
  Processing by OrdersController#create as HTML
    Parameters: {"authenticity_token"=&gt;”somestring”, "utf8"=&gt;"✓", "back_button"=&gt;"Back"}
    Cart Load (0.3ms)  SELECT `carts`.* FROM `carts` WHERE `carts`.`id` = ? LIMIT 1  [["id", 1]]
    Land Load (2.4ms)  SELECT `lands`.* FROM `lands` 
    CartItem Load (0.5ms)  SELECT `cart_items`.* FROM `cart_items` WHERE `cart_items`.`cart_id` = 1
     (0.3ms)  SELECT MAX(`cart_items`.`length`) AS max_id FROM `cart_items` WHERE `cart_items`.`cart_id` = 1
     (0.4ms)  SELECT MAX(`cart_items`.`width`) AS max_id FROM `cart_items` WHERE `cart_items`.`cart_id` = 1
    CACHE (0.0ms)  SELECT `lands`.* FROM `lands` 
    Shippingservice Load (0.7ms)  SELECT `shippingservices`.* FROM `shippingservices` INNER JOIN `zones` ON `zones`.`id` = `shippingservices`.`zone_id` INNER JOIN `lands_zones` ON `lands_zones`.`zone_id` = `zones`.`id` INNER JOIN `lands` ON `lands`.`id` = `lands_zones`.`land_id` WHERE `lands`.`id` = 1 AND (weightmin &lt;= 50 AND weightmax &gt;= 50 AND heightmin &lt;= 3 AND heightmax &gt;= 3 AND shippingservices.shippingcarrier = ‘1’) AND (lengthmax &gt;= 210 AND widthmax &gt;= 149)
    Product Load (0.3ms)  SELECT `products`.* FROM `products` WHERE `products`.`id` = 3 LIMIT 1
    Hero Load (0.2ms)  SELECT `heros`.* FROM `heros` WHERE `heros`.`id` = 18 LIMIT 1
    Rendered orders/_shipping_step.html.erb (16.5ms)
    Rendered orders/new.html.erb within layouts/application (18.4ms)
    Rendered layouts/_header.html.erb (0.2ms)
    Rendered layouts/_footer.html.erb (0.1ms)
  Completed 200 OK in 109ms (Views: 24.0ms | ActiveRecord: 5.1ms)
  </code></pre>
  
  <p><strong>UPDATE</strong></p>
  
  <p>This is the part from my <code>orders_controller.rb</code></p>
  
  <pre><code>before_filter :initialize_cart
  
  def new
    session[:order_params] ||= {}
    @order = Order.new(session[:order_params])
    @order.current_step = session[:order_step]
    @shippingservices = @cart.available_shipping_services.joins(:lands).where(:lands =&gt; {:id =&gt; session[:cart_params]})
  end
  
  def create
    session[:order_params].deep_merge!(params[:order]) if params[:order]
    @order = Order.new(session[:order_params])
    @shippingservices = @cart.available_shipping_services.joins(:lands).where(:lands =&gt; {:id =&gt; session[:cart_params]})
    @order.current_step = session[:order_step]
    if @order.valid?
      if params[:back_button]
        @order.previous_step
      elsif @order.last_step? &amp;&amp; params[:commit] == 'Option A'
        …
      elsif @order.last_step? &amp;&amp; params[:commit] == 'Option B'
        …
      else
        @order.next_step
      end
      session[:order_step] = @order.current_step
    end
    if @order.new_record?
      render "new"
    else
      # Empty the cart
      @cart.cart_items.destroy_all
      # Reset session
      session[:order_step] = session[:order_params] = nil
    end
  end
  </code></pre>
  
  <p>When I specify an id such as through Land.first.id or Land.last.id, the query works and the back step appears to be working.</p>
  
  <p>When using <code>session[:order_params]</code> I get <code>ActiveRecord::StatementInvalid in Orders#create</code> but the correct land_id is present:</p>
  
  <pre><code>Mysql::Error: Unknown column 'id.ship_to_last_name' in 'where clause': SELECT `shippingservices`.* FROM `shippingservices` 
  INNER JOIN `zones` ON `zones`.`id` = `shippingservices`.`zone_id` 
  INNER JOIN `lands_zones` ON `lands_zones`.`zone_id` = `zones`.`id` 
  INNER JOIN `lands` ON `lands`.`id` = `lands_zones`.`land_id` 
  WHERE `id`.`ship_to_last_name` = 'Smith' 
  AND `id`.`ship_to_address` = 'Somewherestreet' 
  AND `id`.`ship_to_city` = 'Nowheretown' 
  AND `id`.`ship_to_postal_code` = '99999' 
  AND `id`.`phone_number` = 'some number' 
  AND `id`.`shippingservice_id` = '34' 
  AND `id`.`email` = 'someone@example.tld' 
  AND `id`.`land_id` = '85' 
  AND `id`.`ship_to_first_name` = 'John' 
  AND (weightmin &lt;= 200 AND weightmax &gt;= 200 AND heightmin &lt;= 12 AND heightmax &gt;= 12 AND shippingservices.shippingcarrier = '1') AND (lengthmax &gt;= 210 AND widthmax &gt;= 149)
  </code></pre>