Using rails 7.1.3.4 and Ruby 3.3.4
I have this code in the controller:
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
here also has a map
which goes through and serializes all the passed things.
It's supposed to return a list based on the map
value.
However, it returns a list of default item_tags
, i.e.:
[{
"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"
}]
But if I do this:
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
It works as expected.
Why is it this way?
PS. I do similar things in other controllers and it works as expected. Only here it's not returning the expected value.
Your block is passed to render
which doesn't do anything:
render json: [1,2,3].map do |i|
{i => i}
end
#=> [1,2,3]
You have to either use {}
instead of do end
or add some parenthesis:
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}]