Reputation: 12072
I have two models with a relation:
Company has_many :quotes
I want to remove an anti-pattern logic and place it in the controller:
<%= Quote.where(company_id: c.id).where(paid: true).count %>
The setup:
Controller:
@companies = Company.all
Views:
<% @companies.each do |c| %>
<%= Quote.where(company_id: c.id).where(paid: true).count %>
<% end %>
I want to show total quotes for each company. While the above works, I do not want that logic in the views. How to put that in the controller?
I have this in controller:
...
@jobs_count = @companies.map do |c| Quote.where(company_id: c.id).where(paid:true) end
...
That does not work. The view page does not use params.
Upvotes: 1
Views: 51
Reputation: 1488
PJSCopeland has made a great suggestion by using a named scope:
class Quote
scope :paid, -> { where paid: true }
end
but I would suggest taking it a step further by keeping "quotes paid count" as a concern of your Company
model:
class Company
def quote_count
quotes.paid.count
end
end
Then in your view:
<% @companies.each do |c| %>
<%= c.quote_count %>
<% end %>
This also makes it easier to unit test you Quote
and Company
models.
Upvotes: 1
Reputation: 3006
Company.has_many :quotes
already allows you to use company.quotes
rather than Quote.where(company_id: company.id)
.
Now, define this scope on the Quote
model:
class Quote
scope :paid, -> { where paid: true }
# ...
end
Now your view can say
<% @companies.each do |c| %>
<%= c.quotes.paid.count %>
<% end %>
... with no need for any changes in the controller.
Does that look better?
Upvotes: 3