PascalTurbo PascalTurbo - 7 months ago 14
Ruby Question

Stop rails url_helper from requesting a lot of unnecessary objects from database

I'm creating a large xml output using rails and there are a lot of urls generated by rails. There are so called items and enclosures. Every item may have one enclosure. So I'm using has_one and belongs_to relation in my model.

I'm using

enclosure_url(item.enclosure, format: :json)


for generating the url.

What I expect: Rails should generate the url based on the id which is stored in the items table.

What now happens is, that rails is fetching each single enclosure from the database which is slowing down my system.

Enclosure Load (2.6ms) SELECT "enclosures".* FROM "enclosures" WHERE "enclosures"."id" = ? LIMIT 1 [["id", 11107]]
Enclosure Load (3.1ms) SELECT "enclosures".* FROM "enclosures" WHERE "enclosures"."id" = ? LIMIT 1 [["id", 11108]]
Enclosure Load (0.7ms) SELECT "enclosures".* FROM "enclosures" WHERE "enclosures"."id" = ? LIMIT 1 [["id", 11109]]
Enclosure Load (1.5ms) SELECT "enclosures".* FROM "enclosures" WHERE "enclosures"."id" = ? LIMIT 1 [["id", 11110]]
Enclosure Load (6.8ms) SELECT "enclosures".* FROM "enclosures" WHERE "enclosures"."id" = ? LIMIT 1 [["id", 11111]]


Is there any trick stopping rails doing this or do I have to generate my url myself?

Answer

IMO you have two options:

1) Use includes to load all enclosures in one query:

@items = Item.where(...).includes(:enclosure)

2) Pass the id of the enclosure to the url builder instead of the object:

enclosure_url(id: item.enclosure_id)

I would prefer the first option, because it ensures that the object you are linking to actually exists.