[] returned from activeRecord Query ???

I'm just getting my sea legs and I have run into something I think is
pretty strange. Why is it that I sometimes get an empty array value
when I iterate over an answer set from an activeRecord query? This code
rocked along through several cycles until it ran aground:

   @tags = Tag.find_by_sql ["select t.* from tags t, entry_tags et where
t.id = et.tag_id and et.entry_id = ?", self.id ]
   @tags.each do |tag|
      puts "tag:#{tag.inspect}"
      tagWords = tag.word.split
      .....
   end

I put the inspect in when I got the undefined method error and ran again
to discover:

tag:[]
gator:66:in `tags': undefined method `word' for []:Array (NoMethodError)

anyone got a clue? what does this mean and how do I get over it?

thanks in advance!
James

Hi, James

  @tags = Tag.find_by_sql ["select t.* from tags t, entry_tags et where
t.id = et.tag_id and et.entry_id = ?", self.id ]
  @tags.each do |tag|
     puts "tag:#{tag.inspect}"
     tagWords = tag.word.split
     .....
  end

Try "puts @tags.inspect"

What's the output looks like?

keisuke fukuda wrote:

Hi, James

  @tags = Tag.find_by_sql ["select t.* from tags t, entry_tags et where
t.id = et.tag_id and et.entry_id = ?", self.id ]
  @tags.each do |tag|
     puts "tag:#{tag.inspect}"
     tagWords = tag.word.split
     .....
  end

Try "puts @tags.inspect"

What's the output looks like?

--
FUKUDA, Keisuke
Tokyo, Japan
Email: keisukefukuda@gmail.com

with both puts in:
[#<Tag id: 5515, word: "Herbal Formula Replaces", stem_id: 5273,
currentRank: 1, lastScan: nil, created_at: "2008-08-05 11:22:32",
updated_at: "2008-08-05 11:22:32">, #<Tag id: 2003, word: "Medicine",
stem_id: 1957, currentRank: 2, lastScan: nil, created_at: "2008-07-30
10:06:48", updated_at: "2008-08-05 11:22:33">, #<Tag id: 5516, word:
"Diabetics", stem_id: 5274, currentRank: 1, lastScan: nil, created_at:
"2008-08-05 11:22:32", updated_at: "2008-08-05 11:22:32">]
tag:#<Tag id: 5515, word: "Herbal Formula Replaces", stem_id: 5273,
currentRank: 1, lastScan: nil, created_at: "2008-08-05 11:22:32",
updated_at: "2008-08-05 11:22:32">
tag:#<Tag id: 2003, word: "Medicine", stem_id: 1957, currentRank: 2,
lastScan: nil, created_at: "2008-07-30 10:06:48", updated_at:
"2008-08-05 11:22:33">
tag:#<Tag id: 5516, word: "Diabetics", stem_id: 5274, currentRank: 1,
lastScan: nil, created_at: "2008-08-05 11:22:32", updated_at:
"2008-08-05 11:22:32">
tag:[]
gator:67:in `tags': undefined method `word' for []:Array (NoMethodError)

It's getting an array from the result, rather than 1.

Ryan Bigg wrote:

It's getting an array from the result, rather than 1.

Ryan,
The puts @tags.inspect definitely prints an array of three items. My
question is why does @tags.each iterate a fourth time with the bogus
empty array value?

James

Show us the entire code please, I'm interested in the ..... part of your original post the most.

Ryan Bigg wrote:

Show us the entire code please, I'm interested in the ..... part of
your original post the most.

Ryan,
That's it! I totally overlooked the fact that I an adding to the @tags
array while I am iterating over it. Here;s the bad code:

@tags = Tag.find_by_sql ["select t.* from tags t, entry_tags et where
t.id = et.tag_id " +
              "and et.entry_id = ?", self.id ]
      puts @tags.inspect
      @tags.each do |tag|
        puts "tag:#{tag.inspect}"
        tagWords = tag.word.split
        if tagWords.length > 1
          tagWords.each do |tagWord|
            @tags << Tag.find_by_sql(["select * from tags where word =
?", tagWord])
          end
        end
      end

Guess I had better check the return from that second find before blindly
adding it in.

Thanks!
James

James Barnard wrote:

with both puts in:
[#<Tag id: 5515, word: "Herbal Formula Replaces", stem_id: 5273,
currentRank: 1, lastScan: nil, created_at: "2008-08-05 11:22:32",
updated_at: "2008-08-05 11:22:32">, #<Tag id: 2003, word: "Medicine",
stem_id: 1957, currentRank: 2, lastScan: nil, created_at: "2008-07-30
10:06:48", updated_at: "2008-08-05 11:22:33">, #<Tag id: 5516, word:
"Diabetics", stem_id: 5274, currentRank: 1, lastScan: nil, created_at:
"2008-08-05 11:22:32", updated_at: "2008-08-05 11:22:32">]
tag:#<Tag id: 5515, word: "Herbal Formula Replaces", stem_id: 5273,
currentRank: 1, lastScan: nil, created_at: "2008-08-05 11:22:32",
updated_at: "2008-08-05 11:22:32">
tag:#<Tag id: 2003, word: "Medicine", stem_id: 1957, currentRank: 2,
lastScan: nil, created_at: "2008-07-30 10:06:48", updated_at:
"2008-08-05 11:22:33">
tag:#<Tag id: 5516, word: "Diabetics", stem_id: 5274, currentRank: 1,
lastScan: nil, created_at: "2008-08-05 11:22:32", updated_at:
"2008-08-05 11:22:32">
tag:[]
gator:67:in `tags': undefined method `word' for []:Array (NoMethodError)

I'm not sure what the extra empty Array is, but why don't you use
ActiveRecord's has_and_belongs_to_many relationship? Your custom SQL
seems a little bit tricky.

Keisuke Fukuda wrote:

James Barnard wrote:

updated_at: "2008-08-05 11:22:32">
tag:#<Tag id: 2003, word: "Medicine", stem_id: 1957, currentRank: 2,
lastScan: nil, created_at: "2008-07-30 10:06:48", updated_at:
"2008-08-05 11:22:33">
tag:#<Tag id: 5516, word: "Diabetics", stem_id: 5274, currentRank: 1,
lastScan: nil, created_at: "2008-08-05 11:22:32", updated_at:
"2008-08-05 11:22:32">
tag:[]
gator:67:in `tags': undefined method `word' for []:Array (NoMethodError)

I'm not sure what the extra empty Array is, but why don't you use
ActiveRecord's has_and_belongs_to_many relationship? Your custom SQL
seems a little bit tricky.

--
FUKUDA, Keisuke
Tokyo, Japan
Email: keisukefukuda@gmail.com

yes, Keisuke, I probably should. I am just so much more comfortable
writing sql. If I write it, then I can tune it directly and I need
for this to be really fast.

When I am in rails, I do use the has_many and belongs_to associations.

James

Firs of all I do not like to change the array while I iterate through
it.
Second adding the new element to array without validating is not
desirable if you expect that added element behave in particular
fashion.
If you gain is to get some speed of execution by using direct SQL
calls than you should make less SQL calls by means of SQL
programming.
For example make a SQL string split function that return a list of
tags from delimited word field and make your query as one SQL request
that returns all records at ones or make a stored procedure that will
do that job and then optimize that stored procedure.
That will be database dependent but you are targeting a specific
database and to get some speed use all it can provide.