I am trying to retrieve one field from a "has_one :through" association. Assuming I have the following model:
class CreatePersons < ActiveRecord::Migration
def change
create_table :person do |t|
t.string :first_name
t.string :last_name
t.date :age
end
end
def change
create_table :location do |t|
t.decimal :longitude
t.decimal :latitude
t.string :city
t.string :state
t.references :person
end
end
def change
create_table :forecasts do |t|
t.timestamp :time
t.text :summary
t.decimal : precipitation
t.references :location
t.timestamps
end
end
end
... and the following model:
class Location < ActiveRecord::Base
belongs_to :person
belongs_to :forecast
end
class Forecast < ActiveRecord::Base
belongs_to :locaiton
has_one :person, :through => :location
end
class Person < ActiveRecord::Base
end
.. and I want to make query using ActiveRecord that pulls out ONLY the persons first name based on the forecast (i know its stupid, but this is just an excercise); so something like this:
# i realize this is a bad query, i'm putting this here to make my question stronger
Forecast.where("percipitation > ?", 1.5).select(:first_name)
or in SQL terms
select first_name from forecast fc
inner join locaiton loc on loc.id = fc.location_id
inner join person on person.id = loc.person_id
where precipitation > 1.5
SO I have tried something like this:
Forecast.joins(:person).where("percipitation > ?", 1.5).select(:person)
# Forecast.joins(:person).where("percipitation > ?", 1.5).select(:person).to_sql
# select 'person' from forecast fc
# inner join locaiton loc on loc.id = fc.location_id
# inner join person on person.id = loc.person_id
# where fc.percipitation > 1.5
this returns me empty instances of the Forecast object
so then I tried this:
Forecast.joins(:person).where("percipitation > ?", 1.5).select("person.first_name")
# Forecast.joins(:person).where("percipitation > ?", 1.5).select("person.first_name").to_sql
# select 'person.first_name' from forecast fc
# inner join locaiton loc on loc.id = fc.location_id
# inner join person on person.id = loc.person_id
# where fc.percipitation > 1.5
however, this also results in a colleciton of empty Forecast objects
HOWEVER, doing this results in exactly what i want, but this is already after the db has been queried:
result = Forecast.joins(:person).where("precipitation > ?", 1.5)
result.each do |forecast|
puts forecast.person.first_name # => "John", "Bob", "Jim"
end
Why can't I get just the first_name out of the DB using select and pull only first_name out of the database? I'm obviously missing something.