Render: json с дополнительными данными

У меня есть модель под названием Todo, и я делаю это:

format.json { render :json => @todo }

Каждый Todo принадлежит к списку. Я хочу добавить значение @todo.list.completion_percentage в JSON, поскольку мне это нужно, чтобы обновить UI (запрос AJAX), поэтому JSON выглядит примерно так:

{
  "todo": {
    "created_at": "2011-02-26T19:39:43Z",
    "updated_at": "2011-02-26T19:53:13Z",
    "done": true,
    "text": "Apples",
    "id": 10,
    "list_id": 2,
    "user_id": 1,
    "due_date": null



    // BELOW THIS LINE SHOULD BE IMPLEMENTED
    "list": {
      "completion_percentage": 63
    }
  }
}

Я пробовал разные вещи, но никто не работал. Кто-нибудь может мне помочь?

Ответ 1

Вы можете захотеть захватить значение данных JSON, а затем изменить его.

format.json { render :json => JSON::parse(@todo.to_json).merge("list" => { "completion_percentage" => 63 }).to_json }

Ответ 2

Чтобы уточнить ответ Брэндона, попробуйте использовать:
render :json => @todo.attributes.merge({list: { "completion_percentage" => 63 }})

Ответ 3

Просто так, как известно другим, вызов @todo.attributes приведет к отключению пользовательских методов по атрибутам. Например, если у вас в модели Todo есть метод

    def written_date
      self.written_date = self.written_date.utc.beginning_of_day
    end 

И атрибут, называемый writ_date в модели Todo, возвращается только атрибут, который хранится в базе данных.

И вы, за исключением того, что пользовательский метод возвращается, когда вы вызываете @todo.attributes, он не будет.