I've got a API-only Rails 7 app with Ruby 3.1.2. I'm using the jb
gem for serialization of data.
In the app, I have a Part
table, which belongs_to
a Company
. I want to deliver the name of the company the part belongs to in order to avoid having to call a 2nd query just for the company names later down the line.
The actual index action is pretty simple (it's actually paginated with the Pagy gem, but that has no tangible effect here)
@parts = Part.includes(:company)
Problem is, my Parts model is massive, and has around 35 fields that my users need to see. As such, writing out any kind of query, or create, or anything like that is a massive pain and takes up a humongous amount of screen real estate, not to mention being incredibly tedious and error prone to write down.
For example, my jb
file for the Parts index page looks something like this
@parts.map do |part|
{
id: part.id,
part_number: part.part_number,
available: part.available,
#... And so on for another 30 lines
company_name: part.company.name,
company_id: part.company.id
}
end
You can probably spot the problem. The only things I'm even adding to this are the company_name
and ID, yet I still need to write down all 30-odd lines for the other attributes as well.
Is there a way for me to avoid this? I tried using the spread operator, but it errors out on me with
ActionView::Template::Error: no implicit conversion of Part into Hash
@parts.map do |part|
**part,
company_name: part.company.name,
company_id: part.company.id
end
CodePudding user response:
You can use attributes instead of splat operator.
@parts.map do |part|
part.attributes.merge(company_name: part.company.name, company_id: part.company.id)
end
But instead of doing this, you can use includes to fetch company
and can avoid n 1 query