Rober
Rober

Reputation: 6108

Rails controller render json Error: nil is not a symbol

I´m facing quite strange problem.

I have a two Rails controllers, when I try to render as Json an array of objects recovered from db, one is working, the other one with the same code not.

Working example when I write server:3000/boats in the browser, I get all my db boats in json format.

BoatController:

def index

  @boats = Boat.all
  puts @boats
  render :json => @boats          
end

However, when I do the same with departures, like server:3000/departures,

 def index
 if params[:query]
   @departures = Departure.find(:all, :conditions => ['name LIKE ?', "%#   {params[:query]}%"])
  else
  @departures = Departure.all
 end

 puts @departures
 render :json => @departures    
end

The only difference is that boats in DB is a table and departures is a view. But I don´t think this is the problem because in the trace you can see the departures are got from DB.

I get nil is not a symbol:

Started GET "/departures" for 127.0.0.1 at 2013-09-27 23:54:02 +0200
Processing by DeparturesController#index as HTML
Departure Load (2.0ms)  SELECT `departures`.* FROM `departures`
#<Departure:0x0000000407a068>
#<Departure:0x00000004079168>
#<Departure:0x00000004083ca8>
#<Departure:0x00000004081a98>
#<Departure:0x0000000408b250>
#<Departure:0x00000004090458>
#<Departure:0x000000040a0b28>
#<Departure:0x000000040b2d78>
#<Departure:0x000000040b05c8>
Completed 500 Internal Server Error in 10ms

TypeError (nil is not a symbol):
app/controllers/departures_controller.rb:14:in `index'

Any suggestion?

UPDATE: The line 14 is: render :json => @departures.

I have tested next combinations: 1. With render :json => @departures commented. In my browser: server:3000/departures

Started GET "/departures" for 127.0.0.1 at 2013-09-28 09:48:08 +0200
Processing by DeparturesController#index as HTML
DEPRECATION WARNING: Calling #find(:all) is deprecated. Please call #all directly  instead. You have also used finder options. These are also deprecated. Please build a
scope instead of using finder options. (called from c:in `find':)
DEPRECATION WARNING: Relation#all is deprecated. If you want to eager-load a relation,    you can call #load (e.g. `Post.where(published: true).load`). If you want to get
an array of records from a relation, you can call #to_a (e.g. `Post.where(published:  true).to_a`). (called from c:in `find':)
Departure Load (3.0ms)  SELECT `departures`.* FROM `departures` WHERE (name LIKE '%%') 
#<Departure:0x000000041017c0>
#<Departure:0x00000004100410>
#<Departure:0x00000004109fb0>
#<Departure:0x00000004110ab8>
#<Departure:0x0000000411a680>
#<Departure:0x000000041291f8>
#<Departure:0x00000004132988>
#<Departure:0x00000004131bc8>
#<Departure:0x00000004131150>
Rendered departures/index.html.erb within layouts/application (7.0ms)
Completed 200 OK in 66ms (Views: 53.0ms | ActiveRecord: 3.0ms)

It returns the departures perfectly.

  1. If I do an ajax request using getJSON (you can see the data is asked as JSON and the query is working:

    Started GET "/departures?query=l" for 127.0.0.1 at 2013-09-28 09:59:50 +0200 Processing by DeparturesController#index as JSON Parameters: {"query"=>"l"} DEPRECATION WARNING: Calling #find(:all) is deprecated. Please call #all directly instead. You have also used finder options. These are also deprecated. Please build a scope instead of using finder options. (called from c:in find':) DEPRECATION WARNING: Relation#all is deprecated. If you want to eager-load a relation, you can call #load (e.g.Post.where(published: true).load). If you want to get an array of records from a relation, you can call #to_a (e.g.Post.where(published: true).to_a). (called from c:infind':) Departure Load (3.0ms) SELECT departures.* FROM departures WHERE (name LIKE '%l%') # # # # # # # Rendered departures/index.json.jbuilder (3.0ms) Completed 200 OK in 54ms (Views: 38.0ms | ActiveRecord: 3.0ms)

It works too.

  1. However if I add render :json => @departures then in both cases (calling from browser or javascript) I get the same error result:

    Started GET "/departures" for 127.0.0.1 at 2013-09-28 10:02:52 +0200 Processing by DeparturesController#index as HTML DEPRECATION WARNING: Calling #find(:all) is deprecated. Please call #all directly instead. You have also used finder options. These are also deprecated. Please build a scope instead of using finder options. (called from c:in find':) DEPRECATION WARNING: Relation#all is deprecated. If you want to eager-load a relation, you can call #load (e.g.Post.where(published: true).load). If you want to get an array of records from a relation, you can call #to_a (e.g.Post.where(published: true).to_a). (called from c:infind':) Departure Load (3.0ms) SELECT departures.* FROM departures WHERE (name LIKE '%%') # # # # # # # # # Completed 500 Internal Server Error in 69ms

    TypeError (nil is not a symbol): app/controllers/departures_controller.rb:12:in `index'

    Rendered c:/Ruby200-x64/lib/ruby/gems/2.0.0/gems/actionpack-4.0.0/lib/action_dispatch/middleware/templates/rescues/_source.erb (64.0ms) Rendered c:/Ruby200-x64/lib/ruby/gems/2.0.0/gems/actionpack-4.0.0/lib/action_dispatch/middleware/templates/rescues/_trace.erb (4.0ms) Rendered c:/Ruby200-x64/lib/ruby/gems/2.0.0/gems/actionpack-4.0.0/lib/action_dispatch/middleware/templates/rescues/_request_and_response.erb (2.0ms) Rendered c:/Ruby200-x64/lib/ruby/gems/2.0.0/gems/actionpack- 4.0.0/lib/action_dispatch/middleware/templates/rescues/diagnostics.erb within rescues/layout (153.0ms)

If I the query with another model, the method works. As I said, I think it´s related with the fact that departures is a database View instead of a table as the other models.

2º UPDATE

I have replaced the database view with a table and this is the controller:

def index
@departures = Departure.all
render :json => @departures
end

Now, It works. The problem is when I try to do the same with database view. But, I need this view and I don´t know how to solve it.

Upvotes: 0

Views: 1689

Answers (2)

Rober
Rober

Reputation: 6108

I have fixed!

As I told you it was related with the fact that the departures model was linked to a database view. Actually, I´m not completely sure what I made it worked.

What I did:

  1. I dropper the Departures view.
  2. I scaffold the Departures model again.
  3. I db:migrate it. (I saw it created an created_at and updated_at maybe this was the problem).
  4. I dropped the Departures table.
  5. I created the Departures view with same structure as the table (this time adding created_at and updated_at columns with dummy values, because I don´t care).

And thats all, when I do render :json => @departures now works!!

Upvotes: 0

user997786
user997786

Reputation:

def index
  query = params[:query] || ""
  @departures = Departure.find(:all, :conditions => ['name LIKE ?', "%#{query}%"])
end

Upvotes: 1

Related Questions