My user is submitting a request with multiple items. Regardless of how the items are saved into the SQL database, for easier analytics, I need each item to be parsed out and saved as an individual row of data in a Excel file (Google Drive).
In other words, in SQL, a Request looks like this: {:name => "john", :email => "john@gmail.com", :items => ["a", "b", "c"]
, but I need this to translate to a document where there are 3 rows for each item, and the only thing different across the rows is the item.
- Row 1 has Name = John, Email = John@gmail.com, Item = a
- Row 2 has Name = John, Email = John@gmail.com, Item = b
- Row 3 has Name = John, Email = John@gmail.com, Item = c
What I have below works, but I am wondering if it is the most efficient, both from the perspective of:
- Is there an easier way to get the params in the first place?
- Is there an easier way to parse and save the individual data?
Thanks!
MODEL code
class Request < ActiveRecord::Base
serialize :items
validate :must_have_one_item
def must_have_one_item
errors.add(:items, 'You must select at least one item') unless self.items.detect { |i| i != "0" }
end
end
VIEW code
<%= f.check_box(:items, {:multiple => true}, "#{thing}") %>
<%= f.label(:items, "#{thing}") %>
Here, thing
is a part of an iterator function that runs through a predefined list of potential items to be selected.
CONTROLLER code with plenty of comments!
class RequestsController < ApplicationController
def new
@requestrecord = Request.new
end
def create
@requestrecord = Request.new(request_params)
if @requestrecord.save
# Given model/ form code so far, the items are passed through as an array. The remaining comments uses the example: @requestrecord.items = ["water filter", "tent", "0", "0", "0"]. What happens is that "0" represents blank checkboxes
@requestrecord.items.select! { |x| x != "0" } #removes blank checkboxes; @requestrecord.items = ["water filter", "tent"]
num_of_requests = @requestrecord.items.count #counts number of items requested; num_of_requests = 2
i = 0
cloned_request = Hash.new
while i < num_of_requests do
cloned_request[i] = Marshal.load(Marshal.dump(@requestrecord)) #creates a cloned_request[0] = @requestrecord and cloned_request[1] = @requestrecord
cloned_request[i].items = @requestrecord.items.slice(i) #disaggregates the items into the cloned_requests; cloned_request[0].items = "water filter", cloned_request[1].items = "tent"
i += 1
end
cloned_request.each do | key, request |
request.save_spreadsheet
end
else
render 'new'
end
end
private
def request_params
params.require(:request).permit({:items => []})
end
end