"So my next step would be to extract this logic into a separate object.
This is purely a controller concern, so I'm not going to put it in a
model, lib etc. "
I think you're asking some good questions. I agree that controllers should have limited knowledge of AR. For me, an AR model is a thin wrapper around persistence. It's responsibility is to know how to access AR, so that other classes do not have to know. The best way to do that is to wrap the queries with an intention-revealing message on the model. That also gives you a good point to stub, and makes it easier to set message expectations. I think that you're gut is correct that the classes that you abstracted may not be worth the added indirection and complexity.
This first message that I would add to the class may seem minor. But consider Rails 4.
owner = Owner.by_subdomain(request.subdomain)
Otherwise, Rails 4 would break the original with it's new syntax.
owner = Owner.find_by_subdomain(sub) becomes Owner.find_by(subdomain: sub)
It's better to isolate that change in one place.
Similarly, you could have an instance method that wraps this query:
scope = owner.things.where(slug: params.fetch(:slug))
becomes
scope = owner.things_by_slug(params.fetch(:slug))
or maybe
scope = owner.available_things_by_slug(params.fetch(:slug))
Even this seemingly trivial access of AR in the controller can be wrapped.
Thing.where(id: params.fetch(:id))
becomes
Thing.retrieve(params.fetch(:id))
While it may seem like a small win, it wasn't that long ago that we didn't have a :where method, only find. Again, it makes sense to isolate knowledge of AR in one place while naming messages to reveal your intentions.
As for eliminating the if, here's the principle that I follow: Make the decision at the earliest point possible. In this case, that would be your route file.
HTH.
--Paul