[] 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.