0

「has_one :through」関連付けから 1 つのフィールドを取得しようとしています。次のモデルがあると仮定します。

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

...そして次のモデル:

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

.. そして、予測に基づいて人物の名前のみを引き出す ActiveRecord を使用してクエリを作成したい (私はその愚かさを知っていますが、これは単なる演習です)。このようなもの:

# 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)

またはSQL用語で

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

だから私はこのようなことを試しました:

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

これにより、Forecast オブジェクトの空のインスタンスが返されます

それで、私はこれを試しました:

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

ただし、これは空の Forecast オブジェクトのコレクションにもなります

しかし、これを行うとまさに私が望む結果になりますが、これはすでにデータベースが照会された後です:

result = Forecast.joins(:person).where("precipitation > ?", 1.5)

result.each do |forecast|

  puts forecast.person.first_name # => "John", "Bob", "Jim"

end

select を使用して DB から first_name だけを取得し、データベースから first_name だけをプルできないのはなぜですか? 私は明らかに何かが欠けています。

4

1 に答える 1

1

なぜあなたのソリューションがまったく機能するのかわかりません。

このようにしてください:

Forecast.where("precipitation > ?", 1.5).joins(:person).pluck("person.first_name")

名の配列を返します。

select(スコープを取得するために)本当に使用する必要がある場合:

Forecast.where("precipitation > ?", 1.5).joins(:person).select("person.first_name")
于 2014-10-11T16:16:23.047 に答える