0

"has_one : through"연관에서 하나의 필드를 검색하려고합니다. ..레일 4 : ActiveRecord => "선택할 수 없습니다"has_one : db의 필드를 통해

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 

나는 쿼리를 기반으로 만 사람 이름을 꺼내서 액티브를 사용하여 만들고 싶어 :

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 

... 다음과 같은 모델 : 가정 나는 다음과 같은 모델을 가지고 예측 (나는 그것의 어리 석음을 알고있다, 그러나 이것은 다만 운동이다); 이 같은 뭔가 :

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

그러나, 이것은 또한 빈 예측의 colleciton 결과이 내가, 정확하게 원하는 결과 일을하지만

객체하지만 DB가 조회 한 후이 이미 :

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 만 꺼내지 못하는 이유는 무엇입니까? 나는 분명히 뭔가를 놓친다.

+0

을, 나는 잠재적으로 범위를 추가 할 수 있음을 이해하지만, 내 이해의 범위 내에서 단지 나에게 능력을 제공하는 것입니다 수동 쿼리를 실행하고 : file : /// Users/tomek/Library/Application % 20Support/Dash/DocSets/Ruby_on_Rails_4/Ruby % 20on % 20Rails와 같은 select ("person.first_name")와 같은 구문 설탕을 제공하십시오. docset/Contents/Resources/Documents/api.rubyonrails.org/classes/ActiveRecord/Scoping/명명 된/ClassMethods.html # method-i-scope. 하지만 왜 내가 select를 통해 프로젝트를 진행할 수 없는지를 알아 내려고 노력하고 있지만 각 메소드에서 할 수 있습니다. –

답변

1

귀하의 솔루션이 전혀 작동하지 않습니다.

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

처음 이름의 배열을 반환합니다

은 이런 식으로 작업을 수행합니다. 당신이 정말로 사용해야 할 경우

select (범위 얻기 위해) : 또한

Forecast.where("precipitation > ?", 1.5).joins(:person).select("person.first_name") 
+0

왜 이렇게 말합니까? "솔루션이 전혀 작동하지 않는 이유를 모르겠습니다." ?? –

+1

가입 할 테이블을 지정해야하기 때문에. Forecast에서 person_name을 (를) 선택하려하지만 join 절에 person 테이블을 지정하지 않았습니다. 예측 테이블에서 first_name 열을 찾으려고하기 때문에 ActiveRecord가 예외를 발생시켜야합니다. – chumakoff

+0

좋아요,하지만 Forecast to Person에 has_one 절이 있습니다. 자동으로 참여를 돕지 않습니까? –