Trying to seed data from seeds.rb within a class structure

Hey all,

I created this in seeds.rb because I want to avoid duplication as much
as possible:

class DataGenerator
def initialize
@current_user = User.first
end

def posts!
Title.each do |t|
Body.each do |b|
post! t, b, @current_user.id
end
end
end
end

class StaticDataGenerator < DataGenerator
def initialize
super
@created_at = “2011-04-04”.to_date
@updated_at = “2011-05-04”.to_date
@published = false
end

def post!(title, body, user_id, options = {})
defaults = {
:title => title,
:body => body,
:created => @created_at,
:updated => @updated_at,
:published => @published,
:user_id => user_id
}
blog_post = BlogPost.create!(defaults.merge(options))
end
end

class RandomDataGenerator < DataGenerator
def initialize
super
end
end

Title = [“ABC”,“DEF”,“GHI”,“JKL”]
Body = [“MNO”,“PQR”,“STU”,“VWX”]

So basically what should happen is a new blog_posts record is written to
the database populated with default values like in the following sql
statement:
INSERT INTO blog_posts
(title,body,created_at,updated_at,published,user_id)
VALUES(“ABC”,“MNO”,2011-04-04,2011-05-04,0,1)

However, when I run rake db:seed, nothing happens. I suspect that it’s
the class structure of my script that’s not being triggered when I run
db:seed. Any idea how to address this?

Thanks for response.

Have you tried adding:

StaticDataGenerator.new.posts!

to the end of your file?

On Tue, Apr 5, 2011 at 2:34 PM, Kendall G. [email protected]
wrote:

Have you tried adding:

StaticDataGenerator.new.posts!

Yeah, that would make sense. I have run into that before where
validation or
something fails. BYW, does anyone know if there is a way to invoke the
debugger during rake db:seed or for that matter any other rake task? I
dont
think I have ever been successful at this. Maybe have to include
ruby-debug
or the like?

On Tue, Apr 5, 2011 at 3:45 PM, David K.
[email protected]wrote:

or something fails. BYW, does anyone know if there is a way to invoke the
debugger during rake db:seed or for that matter any other rake task? I dont
think I have ever been successful at this. Maybe have to include ruby-debug
or the like?

You can add --trace to the end of your rake command. It’s not a debug
per se
but will show you what is going on with the rake command at the time. I
also
like to add a puts statement at the beginning of any call in my rake
file.
Something like “Begin seeding posts…” then on the next call “Begin
seeding
comments…”. It helps when you didn’t or forgot to add the --trace flag
to
see where you are in the process in case it hangs.

B.

On Tuesday, April 5, 2011 4:37:58 PM UTC-6, Ruby-Forum.com User wrote:

Kendall G. wrote in post #991124:

Have you tried adding:

StaticDataGenerator.new.posts!

to the end of your file?

Thanks for response. yes, that worked.

Cool.

end
Body array and then index 1 of the Title array with index 1 of the Body
array and so forth.

But what my posts! method does is this:

and so forth. See how it generates index 0 of Title with all the indexes
of Body and does it for the other indexes of Title as well.

I believe it’s my misunderstanding of the nested block:

Title.each do |t|
Body.each do |b|
post! t, b, @current_user.id
end
end

Yes, what you were expecting would have been “parallel iteration” (any
experts know if there is a more correct term for this?). What you did
was
“nested iteration” (?). In nested iteration (what you did) your
variables at
your “innermost” scope will, over the course of the iterations, describe
the
“cartesian product” (Cartesian product - Wikipedia) of
the
sets that you’re iterating over. So, with two sets a and b, the total
number
of combinations (tuples) will be a.length * b.length.

I thought this would iterate through the first index of Title as local

variable t and then iterate through first index of Body as local
variable b and then pass them into argument list of post! And then when
the outer block ended, it would go to the next index and repeat same
process

Anyone know what I am doing wrong and how to get it to match index to
index not index to all the other indexes?

One way to do what you want would be (assuming Title and Body will
always
contain the same number of elements):

def posts!
Title.each_with_index do |t, i|
post! t, Body[i], @current_user.id
end
end

I’m sure there are more clever, ruby-ish ways for parallel iteration
that
using #each_with_index.

P.S. - (nyone feel free to correct this or comment if I’m wrong here)
here’s
a style recommendation: constants such as Class instances (a.k.a class
and
module definitions or constants that “act” like them) are usually
written
with only the first letter capitalized. Constants of other types (like
your
arrays of strings) are usually ALL_CAPS.

P.P.S. - You may also be interested in the following Ruby syntactic
sugar:

TITLE = %w{ ABC DEF GHI JKL }
BODY = %w{ MNO PQR STU VWX }

This of course only works when all the strings in your array are simple
and
don’t contain any whitespace.

I’m sure there are more clever, ruby-ish ways for parallel iteration that
using #each_with_index.

Okay, I couldn’t help myself. Here’s another alternative/example for
this
kind of “parallel iteration”

fruits = %w{ apples pineapples oranges }
states = %w{ Washington Hawaii Florida }

states.zip(fruits) do |state, fruit|
puts “#{state} grows #{fruit}”
end

def posts!
Title.each_with_index do |t, i|
post! t, Body[i], @current_user.id
end
end

each_for_index is very helpful. Thanks a lot for responses.

On 5 April 2011 21:45, David K. [email protected] wrote:


does anyone know if there is a way to invoke the
debugger during rake db:seed or for that matter any other rake task?

rdebug rake whatever

Colin

Kendall G. wrote in post #991124:

Have you tried adding:

StaticDataGenerator.new.posts!

to the end of your file?

Thanks for response. yes, that worked. That makes sense that you need to
call a method in client code for it to do anything. I do have one
unexpected result. This method right here:

def posts!
Title.each do |t|
Body.each do |b|
post! t, b, @current_user.id
end
end
end

I was expecting it to generate a combination like this:
“ABC” “MNO”
“DEF” “PQR”
“GHI” “STU”
“JKL” “VWX”

See how it corresponds index 0 of the Title array with index 0 of the
Body array and then index 1 of the Title array with index 1 of the Body
array and so forth.

But what my posts! method does is this:

“ABC” “MNO”
“ABC” “PQR”
“ABC” “STU”
“ABC” “VWX”
“DEF” “MNO”
“DEF” “PQR”
“DEF” “STU”
“DEF” “VWX”

and so forth. See how it generates index 0 of Title with all the indexes
of Body and does it for the other indexes of Title as well.

I believe it’s my misunderstanding of the nested block:

Title.each do |t|
Body.each do |b|
post! t, b, @current_user.id
end
end

I thought this would iterate through the first index of Title as local
variable t and then iterate through first index of Body as local
variable b and then pass them into argument list of post! And then when
the outer block ended, it would go to the next index and repeat same
process

Anyone know what I am doing wrong and how to get it to match index to
index not index to all the other indexes?

Thanks for response.