How to get one columns as an array from database


#1

I have a table named “Projects” which has a column “name”. I want to get
a string array to represent all the name values. In the controller, I
can use this code “@projects = Project.find(:all)” to get all the
projects but how to convert it to the string array?

thanks.


#2

On Fri, Dec 26, 2008 at 3:00 AM, Zhao Yi
removed_email_address@domain.invalid wrote:

I have a table named “Projects” which has a column “name”. I want to get
a string array to represent all the name values. In the controller, I
can use this code “@projects = Project.find(:all)” to get all the
projects but how to convert it to the string array?

Maybe a map will do the trick

@project_names = Project.all.map { |p| p.name }


Gabriel L. removed_email_address@domain.invalid


#3

Maybe this is a bit off topic… I never knew you could use syntax like
Project.all. When was this added to the language/framework?


#4

Gabriel L. wrote:

Maybe a map will do the trick

@project_names = Project.all.map { |p| p.name }


Gabriel L. removed_email_address@domain.invalid

Thanks, it works.


#5

A more efficient way is to do this is:

@project_names = Project.all(:select => ‘name’).map(&:name)


#6

Ryan wrote:

I think it’s been around since Rails 2.1

Project.first
Project.last
Project.all

all work.

I think the first last and all refers to rows. I want to select columns.


#7

I think it’s been around since Rails 2.1

Project.first
Project.last
Project.all

all work.


#8

Zhao Yi wrote:

I think the first last and all refers to rows. I want to select columns.

If I’m not wrong, relational algebra doesn’t identify a sequence between
the elements of a row, i.e., I don’t think it gives you the ability to
select a column specifically. That said, you could probe for the schema
and get the elements using that - something like how the dynamic
scaffold used to work in earlier Rails.

Cheers,
Mohit.
12/26/2008 | 1:27 PM.


#9

Ryan wrote:

A more efficient way is to do this is:

@project_names = Project.all(:select => ‘name’).map(&:name)

Yes the map is what I am looking for.

thanks.


#10

Zhao,

I think the most straightforward way is using columns.map
(Project.columns.map { |c| puts c.name }), just like the inspect
method of ActiveRecord:

inspect()

Returns a string like ‘Post id:integer, title:string, body:text‘

File vendor/rails/activerecord/lib/active_record/base.rb, line 1348

1348: def inspect
1349: if self == Base
1350: super
1351: elsif abstract_class?
1352: “#{super}(abstract)”
1353: elsif table_exists?
1354: attr_list = columns.map { |c| “#{c.name}: #{c.type}” }

  • ', ’
    1355: “#{super}(#{attr_list})”
    1356: else
    1357: “#{super}(Table doesn’t exist)”
    1358: end
    1359: end

Cheers, Sazima


#11

On another side note:

@Ryan - You wrote:

A more efficient way is to do this is:
@project_names = Project.all(:select => ‘name’).map(&:name)

While you’ve made a database optimisation there, you’ve also used the
shorthand notation for the map function. I read somewhere that map
(&:name) is quite a bit less efficient than map{ |p| p.name }

unfortunately I can’t find the article that convinced me in the first
place… I can only find this blog with the issue mentioned in the
comments:

http://blog.hasmanythrough.com/2006/3/7/symbol-to-proc-shorthand


#12

Cool. Learn something new all the time.

Thanks.


#13

Jonathan F. wrote:

On another side note:

@Ryan - You wrote:

A more efficient way is to do this is:
@project_names = Project.all(:select => ‘name’).map(&:name)

While you’ve made a database optimisation there, you’ve also used the
shorthand notation for the map function. I read somewhere that map
(&:name) is quite a bit less efficient than map{ |p| p.name }

unfortunately I can’t find the article that convinced me in the first
place… I can only find this blog with the issue mentioned in the
comments:

http://blog.hasmanythrough.com/2006/3/7/symbol-to-proc-shorthand

The Symbol#to_proc syntax is slower than a block, but unless you’re
doing it thousands of times, the single trip to the database is probably
at least a few orders of magnitude more expensive.