James Pleasant
James Pleasant

Reputation: 707

Collection returned by .where not responding as expected

I'm trying to define a new array through a where query but I can only get it to work one way.

Here it is:

<%   

 @children = Array.new
 Topic.where(breadcrumb_id: @topic.id).each do |y|
     @children.push(y.name)
 end


 return @children
 %>


 Returns the array ["Performance Arts", "Visual Arts", "Physical Arts", "Music", "Culinary Arts"] (All topics)

But I would prefer just to do

  @children = Topic.where(breadcrumb_id: @topic.id)

  return @children.each.name

  Returns "undefined method `name' for #<Enumerator:0x007fe92205a1f0>"

For whatever reason .each won't respond correctly... although it works on the initial where call in the first example. What's the difference?

and Is there a way to do this so that I can pull the names directly through the array?

Upvotes: 0

Views: 88

Answers (3)

Teoulas
Teoulas

Reputation: 2963

On Rails 3.2 there's also pluck:

@children = Topic.where(breadcrumb_id: @topic.id).pluck("name")

This has the extra benefit of doing a SELECT name FROM ... instead of SELECT *

Upvotes: 2

Lars Haugseth
Lars Haugseth

Reputation: 14881

The #where method returns an ActiveRecord::Relation object, not an array.

To get an array, call #all or #to_a on it:

@children = Topic.where(breadcrumb_id: @topic.id).all
@children = Topic.where(breadcrumb_id: @topic.id).to_a

Note that you don't need to convert it to an array in order to iterate over it.

Check out Frederick Cheung's answer to why your use of #each doesn't work.

Upvotes: 1

Frederick Cheung
Frederick Cheung

Reputation: 84132

That's just not what each does. You might be looking for map (or its alias), collect

Topic.where(...).map {|topic| topic.name}

You can make that a little shorter using the Symbol#to_proc shortcut:

Topic.where(...).map &:name

Upvotes: 3

Related Questions