0

Right now, when a user creates a Request object, the output looks like this:

<Request id: 1, email: "abc@yahoo.com", items: ["one item", "two item"], created_at: "2014-04-24 05:14:24", edit_id: "gwe3EX4q2EUVk7FQCRUJug">

I am trying to convert this so that if items > 1, the output is split into two Request instances like so:

<Request id: 1, email: "abc@yahoo.com", items: "one item", created_at: "2014-04-24 05:14:24", edit_id: "gwe3EX4q2EUVk7FQCRUJug">

<Request id: 2, email: "abc@yahoo.com", items: "two item", created_at: "2014-04-24 05:14:24", edit_id: "gwe3EX4q2EUVk7FQCRUJug">

What's complicating this further is that also I want the Request.id to increment as per usual, but NOT the created_at and edit_id, both of which are automatically generated when a Request.create is called.

How can I do this? The code snippet of the method I've worked on so far (certainly not working, I'm stumped)...

self.items.each_with_index do |item, index|
      index = Request.save(:email => self.email, :items => item, :created_at => self.created_at, :edit_id => self.edit_id)
end

Thanks!

FYI the code for the edit_id method:

def Request.new_edit_id
  SecureRandom.urlsafe_base64
end

def create_edit_id
  self.edit_id = Request.new_edit_id
end

UPDATE:

Also, the clone or dup methods that create shallow copies don't work in this case. The first answer on this question: How do I copy a hash in Ruby? works for a simple array, but for a complex hash like what I have, changing the cloned copy will actually change the original as well.

I'm going to explore a deep copy and see if I can get that to work!

Community
  • 1
  • 1
james
  • 3,989
  • 8
  • 47
  • 102
  • you can't actually call `save` on an `ActiveRecord` subclass, it should be called on instances so you want to use `create` instead of `save` and I am guessing it should work fine as: `self.items.each { |item| self.class.create!(:email => self.email, :items => item, :created_at => self.created_at, :edit_id => self.edit_id) }` – bjhaid May 26 '14 at 00:09

1 Answers1

0

In the process of figuring this out, I learned that it's bad practice to store array data like this in an object. I should just be making another data table and relating the two.

That said, if any bit of this code is helpful, here's what did it:

@requestrecord.items = ["water filter", "tent"]
num_of_requests = @requestrecord.items.count 

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

Note the Marshal.load(Marshal.dump(@requestrecord)) creates a deep copy and therefore works where clone and dup would not. (They would create references to the original hash. If the original hash changed, so would they. Moreover, I found out that in complex hashes like what I was building, changing a cloned hash actually changes the original as well!)

james
  • 3,989
  • 8
  • 47
  • 102