Reputation: 10699
I have the following active record model:
class Dispatch < ActiveRecord::Base
has_one :waypoint
end
When accessing the waypoint object, the generated query retrieves all columns from the model:
pry(main)> d.waypoint
Waypoint Load (0.5ms) SELECT `waypoints`.* FROM `waypoints`
WHERE `waypoints`.`waypointable_id` = <dispatch_id>
LIMIT 1
If I want to retrieve specific columns from the dispatch's waypoint then I should use the select
scope for has_one
ApiDock reference, section 4.2.3. Unfortunately, that approach throws a NoMethodError
:
pry(main)> d = Dispatch.last
pry(main)> d.waypoint.select('latitude, longitude')
Waypoint Load (19.4ms) SELECT `waypoints`.* FROM `waypoints`
WHERE `waypoints`.`waypointable_id` = <some_id> LIMIT 1
NoMethodError: private method `select' called for #<Waypoint:0x007fe77ed79c28>
What am I missing? I tried with ActiveRecord 4.0.11 and 4.2.0.
The underlying query should be something like this:
SELECT latitude, longitude FROM `waypoints`
WHERE `waypoints`.`waypointable_id` = <some_id>
LIMIT 1
I know I could just do
Waypoint.where(waypointable_id: <some_id>).select('latitude, longitude').last
but that misses the whole point of the has_one
association. And since it is a feature specified in the docs then it should work properly, right?
Upvotes: 1
Views: 1432
Reputation: 13067
Try:
Waypoint.select('latitude, longitude').where(...)
Activerecord select
is a class method : http://guides.rubyonrails.org/active_record_querying.html#selecting-specific-fields
Upvotes: 1
Reputation: 4744
By default has_one retrieves the whole object but if you need to override this you cannot call select on the retrieved object because select is a class method.
try ::
has_one :waypoint, -> { select "latitude, longitude"}
this will return by default only the latitude and longitude.
Upvotes: 0