Reputation: 6108
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.
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:in
find':)
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.
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:in
find':)
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
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:
And thats all, when I do render :json => @departures now works!!
Upvotes: 0
Reputation:
def index
query = params[:query] || ""
@departures = Departure.find(:all, :conditions => ['name LIKE ?', "%#{query}%"])
end
Upvotes: 1