creating hash and putting form content into it

I've got a form with fields of this naming convention:
<Customer Info>
First Name: <input type="text" name="customer[first_name]" ...
Last Name: <input type="text" name="customer[last_name]" ...
Address: <input type="text" name="customer[address_1]" ...
City: <input type="text" name="customer[city]" ...
State: <input type="text" name="customer[state]" ...
<Billing Info>
First Name: <input type="text" name="billing_address[first_name]"...
Last Name: <input type="text" name="billing_address[last_name]"...
Address: <input type="text" name="billing_address[address_1]"...
City: <input type="text" name="billing_address[city]"...
State: <input type="text" name="billing_address[state]"...

And I can successfully use params[:customer] to access all the
customer items and params[:billing_address] for the billing info. And
I can successfully use Hash(params[:customer]) to create a new
customer and populate a table. The problem I'm having is if they
identify that the billing info is the same as their customer info,
then I want to put the customer info into a billing hash to use to
update/create a record in the billing table. This code doesn't work
for creating the hash (but doesn't generate an error either):

    begin
      billing_address_hash = Hash.new()
      if (params[:different_billing_info] == "1")
        billing_address_hash.merge(params[:billing_address])
        #puts("\nDifferent: ", billing_address_hash.to_s)
      else
        billing_address_hash.merge(params[:customer])
        #puts("\nSame: ", billing_address_hash.to_s)
        # Remove customer fields not found in the billing address
table
        billing_address_hash.delete('status')
        billing_address_hash.delete('email')
      end
    rescue
      @error_message = "Unable to create billing address hash.<br>"
      @request_completed = false
      return
    end

It just returns the initialized new billing_address_hash as empty. If
I use Hash(params[:billing_address]) (or customer) in place for the
parameter for merge, an error occurs and the error message is
returned.

How do I get params[] data into a hash that the Hash merge method will
take as a parameter?

The reason I'm doing something like this is that I have additional
fields in the customer model that are not in the billing_address
model. I'm assuming if I try to pass all the customer fields into the
billing model, it will cause an error.

Jack wrote:
:

    begin
      billing_address_hash = Hash.new()
      if (params[:different_billing_info] == "1")
        billing_address_hash.merge(params[:billing_address])
        #puts("\nDifferent: ", billing_address_hash.to_s)
      else
        billing_address_hash.merge(params[:customer])
        #puts("\nSame: ", billing_address_hash.to_s)
        # Remove customer fields not found in the billing address
table
        billing_address_hash.delete('status')
        billing_address_hash.delete('email')
      end
    rescue
      @error_message = "Unable to create billing address hash.<br>"
      @request_completed = false
      return
    end

It just returns the initialized new billing_address_hash as empty. If

Can you try with merge! instead of merge ?

Stephan

# irb

a = {:a => 1}; b = {:b => 2}

=> {:b=>2}

a.merge(b)

=> {:b=>2, :a=>1}

a

=> {:a=>1}

b

=> {:b=>2}

a.merge!(b)

=> {:b=>2, :a=>1}

a

=> {:b=>2, :a=>1}

b

=> {:b=>2}

Thanks Stephan. You at least pointed me to the correct method. merge
returns a new hash, which I wasn't saving. But merge! adds content to
the existing hash. I'm still getting an empty hash though using
something like this:

    billing_address_hash = Hash.new()
    begin
      if (params[:different_billing_info] == "1")
        billing_address_hash.merge!(Hash[params[:billing_address]])
        logger.info("\nDifferent: ", billing_address_hash.to_s)
      else
        billing_address_hash.merge!(Hash[params[:customer]])
        logger.info("\nSame: ", billing_address_hash.to_s)
        # Remove customer fields not found in the billing address
table
        billing_address_hash.delete('uva_status')
        billing_address_hash.delete('email')
      end
    rescue
      @error_message = "Unable to create billing address hash.<br>"
      @request_completed = false
      return
    end

which baffles me because I use Hash[params[:customer]] to pass the
form data to the customer model when creating a new one and it works
just fine.

Jack wrote:

If you post more controller code, that should make it easier to track
down.

Stephan

Here's the entire method that is when the form is submitted.
Everything up to the billing_address_hash works. (Note: Before adding
that section the last if construct, ie. @request.agency_id was
functioning successfully when it was passed
Hash[params[:billing_address]] as the last parameter. I needed to
change this in the event an external customer did not include a
separate billing address.)

  # Save all the details entered for a request to the database, making
sure to flag the order as unapproved
  def save_details
    # Set a flag to determine if the request data is all good if this
method returns at the end
    # without this value being modified.
    @request_completed = true
    @error_message = ''

    # Get the form customer contact information.
    form_customer = Customer.new(Hash[params[:customer]])
    # Get/create the department's id to store in the customer record
    form_department_name = params[:department_name]
    form_customer.department_id =
Department.get_id(form_department_name)
    # Identify how the customer heard about the service.
    form_heard_about_service_other =
params[:heard_about_service_other]
    form_customer.heard_about_service_id =
HeardAboutService.existing_or_other_id(form_customer.heard_about_service_id,form_heard_about_service_other)
    # Determine if this is a returning customer using the email
address. If so then
    # update their existing information. Otherwise create a new
customer record.
    existing_customer = Customer.find(:first, :conditions => ["email
= ?", form_customer.email])
    begin
      if (existing_customer != nil)
        existing_customer.update_attributes!(Hash[params[:customer]])
        existing_customer.update_attributes!({'department_id' =>
form_customer.department_id, 'heard_about_service_id' =>
form_customer.heard_about_service_id})
        @customer = existing_customer
      else
        form_customer.save!
        @customer = form_customer
      end
    rescue
      # If any error occurs when saving the customer information then
the request submission fails
      # since we need to be able to tie the request to a valid
customer record.
      @error_message += "Customer information could not be saved!<br>"
      @request_completed = false
      return
    end

    # Get the form's general order request info.
    @request = Request.new(Hash[params[:order]])
    @request.is_approved = 0
    # Assign the customer's id to this new order
    @request.customer_id = @customer.id
    # Make sure the date due is formatted correctly before writing to
the table
    # parsedate returns an array with year, month, day as first three
elements.
    begin
      date_due = ParseDate.parsedate(params[:order][:date_due],true)
      @request.date_due =
Date.new(date_due[0],date_due[1],date_due[2]).to_s + ' 17:00:00'
    rescue # if an invalid date was entered set to nil
      @request.date_due = nil
    end
    # Set the request date for the order to the current date and time
    @request.date_request_submitted = Time.now.strftime("%Y-%m-%d %H:
%M:%S")
    # Make sure that external customers have the availability set to
Public
    if (@session[:computing_id] == 'External')
      @request.availability = 'Public'
    end
    # Create a new request/order record.
    begin
      @request.save!
    rescue
      # If the request cannot be saved to the order table then we
should not continue
      @error_message += "Unable to create a new request at this
time.<br>"
      @request_completed = false
      return
    end

    # NOTE: Before attempting to use the billing fields, determine if
the billing info is different
    # than the regular customer info. Because if the person
affiliation is external then the billing
    # address will be empty by default and the different billing
address box not checked.
    billing_address_hash = Hash.new()
    begin
      if (params[:different_billing_info] == "1")
        billing_address_hash.merge!(Hash[params[:billing_address]])
        logger.info("\nDifferent: ", billing_address_hash.to_s)
      else
        billing_address_hash.merge!(Hash[params[:customer]])
        logger.info("\nSame: ", billing_address_hash.to_s)
        # Remove customer fields not found in the billing address
table
        billing_address_hash.delete('status')
        billing_address_hash.delete('email')
      end
    rescue
      @error_message += "Unable to create billing address hash.<br>"
      @request_completed = false
      return
    end

     # If an agency was specified on the form then search/save the
billing info as agency related.
    # Otherwise it should be related to the customer.
    if (@request.agency_id != nil)
      @billing_address =
BillingAddress.update_or_create('agency_id',@request.agency_id,billing_address_hash)
      logger.info("\nBilling address update using agency")
    else
      @billing_address =
BillingAddress.update_or_create('customer_id',@request.customer_id,billing_address_hash)
      logger.info("\nBilling address update using customer")
    end
  end