0

If I do:

name_array = Model.column_names
name_array.delete_if {|name| ["id","created_at","updated_at"].include?(name)}
pp Model.column_names

The Model.column_names command will return an array without the id, created_at & updated_at column names. It was my presumption that the name_array would have the names deleted and not the Model.column_names array.

Rails 3.0.13 Ruby 1.9.3

ScottJShea
  • 7,041
  • 11
  • 44
  • 67

3 Answers3

5

See the Array documentation for delete_if:

Deletes every element of self for which block evaluates to true. The array is changed instantly every time the block is called and not after the iteration is over.

So when you delete elements from name_array, you are actually deleting them from Model.column_names since they're pointing to the same thing.

If you don't want to do that, duplicate the array before deleting:

name_array = Model.column_names.dup
name_array.delete_if {|name| ["id","created_at","updated_at"].include?(name)}
Chris Salzberg
  • 27,099
  • 4
  • 75
  • 82
2

u can also use reject

a = [1,2,3]
a.reject{|x| x>=2}
=> [1]
Prasad Surase
  • 6,486
  • 6
  • 39
  • 58
2

Dup can help, but there is an restruction. The fact that dup creates 'shallow copy', it has the following non-obvious consequences:

> arr = Model.column_names.dup
=> ["id", "name", "klasse", "cars_count", "klasse_id"] 
> arr.delete('id')
=> "id" 
> arr
=> ["name", "klasse", "cars_count", "klasse_id"] 
> Model.column_names
=> ["id", "name", "klasse", "cars_count", "klasse_id"] 
> arr.each &:upcase!
=> ["NAME", "KLASSE", "CARS_COUNT", "KLASSE_ID"] 
> Model.column_names
=> ["id", "NAME", "KLASSE", "CARS_COUNT", "KLASSE_ID"] 
antiqe
  • 1,125
  • 8
  • 17