Rails 3 unexpected JSON behavior
Models
class Project
has_many :tasks
class Task
belongs_to :project
Task
has the following attributes (among others)
t.string project
t.integer project_id
This is code I inherited and I'm not sure why it has both columns but I noticed an unexpected behavior with this setup. When I render JSON for @task
, it included the project
info as such (may not be properly formatted JSON but you get the idea)
{
"task": {
"duration": 3,
"project": {
"project": {
"id": 9,
"description": "Roofing,
"updated_at": "2011-09-07T16:58:34Z",
...
}
},
"project_id": 9,
...
}
}
I checked开发者_Go百科 project
column in the database and it's nil. Seems like Rails treated that column like a relation call (I can see why even) instead of just a column, is that intended behavior?
I think you are correct in your assumption of a naming collision. You can actually access your task's project like that (task.project
), so when the rails JSON renderer renders task.project
it pulls down the JSON rendition of its relation like you're speculating. I recommend you change the name of that column to not clash with rails' convention, or you can change the name of the relation if you would rather not change the database column (look at the :class_name
option), but it may cause more confusion down the road. I just read that you inherited that code. Usually when you specify model relations, you automatically get attributes such as project_id
, and a helper method project
which accesses the task's project. Perhaps the author of the code was not aware of this and felt the need to create those two columns himself. It might be okay to keep project_id
, but the project
attribute is clearly clashing.
Alternatively, you can override the JSON rendition yourself by defining a method in your model with the signature def as_json(options={})
which returns a hash representing your desired JSON rendition, ex. { :name => task.name, :project => something_else }
.
精彩评论