0

I have this in my controller under the index action:

format.csv do

    @coasters = Coaster.all
    render text: @coasters.to_csv

end

But when I run it I get: undefined method `to_csv' for # I just can;t see where I am going wrong?

The to_csv method is here:

def self.to_csv
    CSV.generate do |csv|
      csv << column_names
      all.each do |coaster|
        csv << coaster.attributes.values_at(*column_names)
      end
    end
  end

Any thoughts?

rctneil
  • 7,016
  • 10
  • 40
  • 83

2 Answers2

3

Your class method to_csv works on relations (scopes), so just write @coasters = Coaster.scoped instead @coasters = Coaster.all:

format.csv do

    @coasters = Coaster.scoped
    render text: @coasters.to_csv

end

Explanation:

Your method to_csv is declared with self. so this is class method. This method can be executed only on Coaster class, not over object or array of objects:

 Coaster.to_csv  #good
 Coaster.find(1).to_csv #error - Coaster object: undefined method 'to_csv'
 Coaster.where('id>5').to_csv #good
 Coaster.where('id>5').all.to_csv #error - return array of objects
 Coaster.all.to_csv #error

Last 3 lines are related with Rails 3 ActiveRecord::Relation: link1, link2. All class method can be executed on ActiveRecord::Relation object, but remember that Coaster.all returns array of objects, not relation.

Coaster.scoped returns ActiveRecord::Relation for all objects: http://apidock.com/rails/ActiveRecord/Scoping/Named/ClassMethods/scoped

rogal111
  • 5,874
  • 2
  • 27
  • 33
  • 2
    ok, Please could you explain that a bit more. I'm still not fully understanding it. Why doesn't Coaster.all work? – rctneil Jul 22 '12 at 16:32
1

Coaster.all returns an array which is not an exception class. So, when you try to raise it you will get the error you are seeing

ramblex
  • 3,042
  • 21
  • 20
  • Sorry, I posted entirely the wrong piece of code. I have updated my question with what I originally wanted to ask! Sorry guys! – rctneil Jul 22 '12 at 13:28