Anyone know how to copy rows?


#1

Hey all,

I’m trying to write something that allows one to copy several rows from
a table and create new rows based on those rows. This will be used to
intentionally duplicate rows. Did I mention that I was having little
luck? I’m from a PHP world, but I’ve been getting really into Rails
lately.

Here’s what I’ve got(assume an event has_many wastes):

def wastePrepopulate
@wastes = Waste.find_all
@wastes.each do |waste|
Event.find(params[:id]).wastes.create(params[:waste])
end
flash[:notice] = ‘The records have been prepopulated.’
redirect_to :action => “showwastes”, :id =>params[:id]
end

If I feed parameters to it using a form, it will create new records with
those parameters, but I can’t get it to use the data from
@wastes=Waste.find_all.

I’m ultimately trying to set up a way to create records based on
existing data. Any help would be GREATLY appreciated.

Cheers,
Monkey


#2

jeff stevens wrote:

Hey all,

I’m trying to write something that allows one to copy several rows from
a table and create new rows based on those rows. This will be used to
intentionally duplicate rows. Did I mention that I was having little
luck? I’m from a PHP world, but I’ve been getting really into Rails
lately.

Here’s what I’ve got(assume an event has_many wastes):

def wastePrepopulate
@wastes = Waste.find_all
@wastes.each do |waste|
Event.find(params[:id]).wastes.create(params[:waste])
end
flash[:notice] = ‘The records have been prepopulated.’
redirect_to :action => “showwastes”, :id =>params[:id]
end

If I feed parameters to it using a form, it will create new records with
those parameters, but I can’t get it to use the data from
@wastes=Waste.find_all.

I’m ultimately trying to set up a way to create records based on
existing data. Any help would be GREATLY appreciated.

Cheers,
Monkey

Something like this should work

@event = Event.find(params[:id])
@wastes = Waste.find_all
@wastes.each do |waste|
data = waste.attributes.reject do |key, value|
key == :id ||
key == :event_id
end
@event.wastes.create(data)
end

First, you don’t to do “Event.find(params[:id])” in a loop since the
result will be the same every time, so sense adding that DB strain.

Second, active record objects have an “attributes” method that dumps
their data to a hash. We take that hash and reject the keys we don’t
want duplicated, in this case the id, since the new rows should have new
ids, and event_id, since we want the new wastes to be associated with
the event we are calling create on.


#3

Is there something here I’m missing? Why not use ActiveRecord’s .clone
method? From api.rubyonrails.org:

“Returns a clone of the record that hasnâ??t been assigned an id yet and
is treated as a new record. Note that this is a “shallow” clone: it
copies the objectâ??s attributes only, not its associations. The extent of
a “deep” clone is application-specific and is therefore left to the
application to implement according to its need.”

So, if you wanted to copy every row of a table, you could call clone on
every row and save those returned copies.


#4

Bryan D. wrote:

Is there something here I’m missing? Why not use ActiveRecord’s .clone
method? From api.rubyonrails.org:

“Returns a clone of the record that hasnâ??t been assigned an id yet and
is treated as a new record. Note that this is a “shallow” clone: it
copies the objectâ??s attributes only, not its associations. The extent of
a “deep” clone is application-specific and is therefore left to the
application to implement according to its need.”

So, if you wanted to copy every row of a table, you could call clone on
every row and save those returned copies.

Heh, didn’t AR had that.

so you can probably rewrire my code as:

@event = Event.find(params[:id])
@wastes = Waste.find_all
@wastes.each do |waste|
new_waste = waste.clone
new_waste.event = @event
new_waste.save
end

As for learning, everything I know is from http://api.rubyonrails.com/
http://www.rubycentral.com/ref/ and the Agile Web D. book.


#5

Alex W. wrote:

jeff stevens wrote:

Hey all,

I’m trying to write something that allows one to copy several rows from
a table and create new rows based on those rows. This will be used to
intentionally duplicate rows. Did I mention that I was having little
luck? I’m from a PHP world, but I’ve been getting really into Rails
lately.

Here’s what I’ve got(assume an event has_many wastes):

def wastePrepopulate
@wastes = Waste.find_all
@wastes.each do |waste|
Event.find(params[:id]).wastes.create(params[:waste])
end
flash[:notice] = ‘The records have been prepopulated.’
redirect_to :action => “showwastes”, :id =>params[:id]
end

If I feed parameters to it using a form, it will create new records with
those parameters, but I can’t get it to use the data from
@wastes=Waste.find_all.

I’m ultimately trying to set up a way to create records based on
existing data. Any help would be GREATLY appreciated.

Cheers,
Monkey

Something like this should work

@event = Event.find(params[:id])
@wastes = Waste.find_all
@wastes.each do |waste|
data = waste.attributes.reject do |key, value|
key == :id ||
key == :event_id
end
@event.wastes.create(data)
end

First, you don’t to do “Event.find(params[:id])” in a loop since the
result will be the same every time, so sense adding that DB strain.

Second, active record objects have an “attributes” method that dumps
their data to a hash. We take that hash and reject the keys we don’t
want duplicated, in this case the id, since the new rows should have new
ids, and event_id, since we want the new wastes to be associated with
the event we are calling create on.

He shoots…he scores!
You are a gentleman and a scholar! It worked perfectly.

As for “Event.find(params[:id])” being part of the loop; that was just
an embarrassing oversight. Your point is clear and well taken.

As for your approach; I wasn’t sure if rails would overwrite the ids
automatically or not. Rejecting attributes makes perfect sense.

Where can I find some good reference. I’ve gone through some tutorials
and bought the Agile Rails book, but that isn’t cutting it. Any ideas?
Is there an up to date Active directory reference? For instance:

data = waste.attributes.reject do |key, value|
key == :id ||
key == :event_id
end

It’s simple, clean and straight forward, but I can’t find any place to
find that kind of usage. I would not have come up with “reject”, but I
should be able to. What did you read to get to where you are? I’m
usually a spounge, but I need some water to soak up. :wink:

Thanks a bunch for your previous reply, it was just what the doctor
ordered!

Cheers,
Monkey