Reputation: 27852
I have the following associations:
A User has_many Hosts
and a Host has_many Orders
I have nested routes for Hosts and Orders, so when a user wants to see Orders, it will have to be through a Host (/hosts/:id/orders
)
I want to avoid users accessing other users orders, so I have this in my index action:
def index
host = current_user.hosts.find(params[:host_id])
redirect_to :back, alert: 'Host was not found' if host.nil?
orders = host.orders.includes(:order_state).order('id ASC')
end
As you can see I am hitting the DB twice. One to find if the host exists for current_user, and another one to find the orders for this host.
How can I do this in just one query?
Upvotes: 2
Views: 51
Reputation: 14402
As already mentioned by sufleR
, there probably isn't an easy way how to distinguish between no orders for the given host
and host not found
. The code, however, can be simpler:
class User < ActiveRecord::Base
has_many :hosts
has_many :orders, through: :hosts # !!!
end
orders = current_user.orders.includes(:order_state).order(:id).
where(host_id: params[:host_id])
Upvotes: 0
Reputation: 2973
Try something like this:
orders = Order.joins(:host)
.includes(:order_state)
.where(hosts: { user_id: current_user.id, id: params[:host_id] })
.order('orders.id ASC')
redirect_to :back, alert: 'Orders for selected host not found' unless orders.any?
If you want to give user alert for host not found you can't do it with one query.
Upvotes: 1