Рендеринг json возвращает другой ответ, передавая буквальное значение и переменную

Использование рельсов 7.1.3.4 и Ruby 3.3.4

У меня есть этот код в контроллере:

    render json: item.item_tags.map do |item_tag|
      {
        things_count: item_tag.tag.things.count,
        other_count: item_tag.tag.other_association.count,
        tag: {
          id: item_tag.tag.id,
          name: item_tag.tag.name,
          slug: item_tag.tag.slug,
          things: ThingSerializer.new.index(item_tag.tag.things),
        }
      }
    end

ThingSerializer здесь также есть map, который проходит и сериализует все прошедшие вещи.

Предполагается, что он вернет список на основе значения map. Однако он возвращает список по умолчанию item_tags, то есть:

[{
    "id": 236,
    "status": "draft",
    "position": 0,
    "item_id": 234,
    "tag_id": 123,
    "inserted_at": "2024-03-19T10:23:56.000+03:00",
    "updated_at": "2024-03-19T10:23:56.000+03:00"
}]

Но если я сделаю это:

    actual_json = item.item_tags.map do |item_tag|
      {
        things_count: item_tag.tag.things.count,
        other_count: item_tag.tag.other_association.count,
        tag: {
          id: item_tag.tag.id,
          name: item_tag.tag.name,
          slug: item_tag.tag.slug,
          things: ThingSerializer.new.index(item_tag.tag.things),
        }
      }
    end

    render json: actual_json

Это работает так, как ожидалось.

Почему именно так?

ПС. Я делаю подобные вещи в других контроллерах, и все работает так, как ожидалось. Только здесь он не возвращает ожидаемое значение.

🤔 А знаете ли вы, что...
Rails активно использует миграции баз данных для управления изменениями схемы.


60
1

Ответ:

Решено

Ваш блок передается render, который ничего не делает:

render json: [1,2,3].map do |i|
  {i => i}
end
#=> [1,2,3]

Вам нужно либо использовать {} вместо do end, либо добавить скобки:

render json: [1,2,3].map { |i|
  {i => i}
}
#=> [{"1":1},{"2":2},{"3":3}]
render(
  json: [1,2,3].map do |i|
    {i => i}
  end
)
#=> [{"1":1},{"2":2},{"3":3}]