Wes Foster
Wes Foster

Reputation: 8900

Rails Creating multiple records with one field different

In my Contract form, I allow the user to select a Unit from a dropdown box, OR select multiple Units from a group of check boxes. The dropdown field is named unit_id and the multiple checkboxes are named multi_unit_ids[]. (since both of these options are on the page, I cannot use the same name).

There is 1 contract created per unit chosen. So if only 1 unit is chosen, then only a single Contract is created with that unit_id. However, when choosing multiple Units, all of the data is the same for each Contract created, however each has their own Unit ID (pulled from the multi_unit_ids array).

Here is the code in my create method of my contracts_controller.rb:

# Multiple Units? Multiple Contracts
if params[:multi_unit_id]
  unit_arr = params[:multi_unit_id]
else
  unit_arr = [*params[:contract][:unit_id]]
end


# Loop through units
unit_arr.each do |unit_id|
  # Assign the unit id to the params for easy creation
  params[:contract][:unit_id] = unit_id

  @contract = Contract.new(params[:contract])
  # ... other code here
  @contract.save
end

This all seems so messy! What is a better way to do this?

Upvotes: 1

Views: 477

Answers (1)

DRobinson
DRobinson

Reputation: 4471

Well I can't make much of a suggestion as far as creating these database entries without a loop goes. I'm not sure whether that's possible, and really that loop doesn't seem messy enough to really stress out about, unless there's a mess in the # ... other code here section that you've omitted.

In fact, what I'm about to suggest might make you feel the code's more messy.

If you plan on creating a lot of database rows, it would probably be a good idea to wrap the loop in an ActiveRecord::Base.transaction similar to:

# Loop through units
ActiveRecord::Base.transaction do
  unit_arr.each do |unit_id|
    # Assign the unit id to the params for easy creation
    params[:contract][:unit_id] = unit_id

    @contract = Contract.new(params[:contract])
    # ... other code here
    @contract.save
  end
end

Or, otherwise use some other means of combining the creation into a single query (there are other options, and benchmarks available at http://www.coffeepowered.net/2009/01/23/mass-inserting-data-in-rails-without-killing-your-performance/).

As far as the refactoring goes, though, I can't offer much here.

Upvotes: 1

Related Questions