2013-08-26 3 views
22

.where() 메서드를 사용하여 연결된 모델 데이터를 검색하는 방법을 알 수 없습니다. 이 예에서는 프로젝트레일 4 : includes() with where() with associated objects 검색하는 방법

앱에서
class Project < ActiveRecord::Base 
    belongs_to :user 
    has_many :videos 
end 

class User < ActiveRecord::Base 
    has_many :projects 
end 

class ProjectsController < ApplicationController 
    def invite 
    @project = Project.includes([:user]).where({:hashed_id=>params[:id]}).first 
    end 

/뷰/프로젝트/invite.html.erg <%= debug(@project) %> 반환 ... 사용자 belongs_to :

는 은
--- !ruby/object:Project 
attributes: 
    id: 22 
    name: Some Project Name 
    belongs_to: 1 
    instructions: Bla bla bla 
    active: true 
    max_duration: 2 
    max_videos: 
    created_at: 2013-08-26 15:56:50.000000000 Z 
    updated_at: 2013-08-26 15:56:50.000000000 Z 
    hashed_id: '1377532589' 
는 는 는

은 관련 사용자 해시/배열은 포함되지해야 이것? 두 번째 전화를 수동으로 추가 할 수 있다는 것을 알고 있습니다. find/where (@project.user = User.where({:id=>@project.belongs_to})하지만 "The Rails Way"와 같은 느낌이 들지 않습니다. 뭐야?

솔루션 내 최초의 질문 (이 배열로 모든 번들 때문에 CakePHP를 작동) debug()가 연관된 객체를 반환 할 것이라는 잘못된 가정하에 공식화했다.

그래서 내 원래 코드 이어야합니다. 그러나 나는 테이블에 정리 된 외래 키의 이름을 잘못 지정했다. 마이 그 레이션 방법 t.belongs_to (올바르게 명명 된 foreign_key 필드 인 이 아닌 필드가 "belongs_to"인 경우)을 보면 혼동을 느낍니다. 그래서 나는 그 열의 이름을 user_id으로 바꿔야 만했습니다. 이제는 아래의 @ Veraticus의 대답에서 설명한대로 작동합니다.

+0

보여줄까요? @ project.user를 보여주는 디버그 출력을 원한다는 것을 의미합니까? 아니면 당신의'where'와'includes'가 작동하지 않는다고 말하는 겁니까? 디버그를 위해'user' 연관을 보여주고 싶다면 여분의'user.where ... '를하지 말고'% = debug (@ project.user) %>'를 시도 했습니까? – lurker

+0

프로젝트 개체가 하나만있는 경우 포함되어 있지 않습니다.여러 프로젝트를 선택하고 하나의 쿼리로 모든 사용자를로드하려는 경우 의미가 있습니다. 또는 당신이 어떻게'include'를 사용하고 있는지, 당신이 기억하기를 바랍니다. – juanpastas

+0

답안은 더 이상 단일 쿼리를 생성하지 않지만,이 접근법은 http://blog.arkency.com/2013/12/rails4-preloading/ – hakunin

답변

37

user 객체가 project 오브젝트의 일부가 아닌, 그래서 당신이 프로젝트를 볼 수 없습니다 : 그것을 발견 할 때, 당신은에 레일 이야기하고 Project.includes(:user) 말해서가 아니라, 참조 관계를 열망을-로드 프로젝트. 이렇게하면 데이터베이스 호출을 절약 할 수 있습니다.

@project = Project.where(id: params[:id]).first # one database call, fetching the project 
@project.user # another database call, fetching the user 

간절히 : 비 열망 예를 들어

@project = Project.includes(:user).where(id: params[:id]).first # one database call, fetching both project and user 
@project.user # no database interaction 

이 열망 로딩 협회는 N + 1 개 데이터베이스 쿼리를 저장할 수 있습니다 has_many 쿼리 문제.

열심히로드하고 로그를 확인한 후 어느 시점에서 @project.user을 호출하여 적절하게 작동하는지 확인할 수 있습니다. 그 시점에서 데이터베이스 호출이 없음을 확인해야합니다.

+0

허. 그래서 * 작동하고 있습니다. 나는 (잘못)'debug'가 연관을 반환 할 것으로 기대하기 때문에 그것을 모릅니다. 말이된다. 그러나, 나는'--- = debug (@ project.user) %>를 얻을 때'---'(아무것도) .' 어떤 아이디어라도? – emersonthis

+0

프로젝트에 사용자가없는 것 같습니다. 제 추측입니다. – Veraticus

+0

당신이 무엇을 의미하는지 확실히 모르겠지만, 나는 그것이 확실하다고 확신합니다. 내 모델이 정의되고 (위 참조) 사용자 테이블에 행이 하나 있습니다. 내가 놓친 게 있니? – emersonthis

6

쿼리로드 최적화는 실제로 단일 호출에서 연관을로드하는 효율적인 방법입니다.

- 포함() 여기서 (와)과 발견() 어떤 경우에는

@project = Project.includes(:user).where(hashed_id: params[:id]).first 
@project = Project.where(hashed_id: params[:id]).includes(:user).first 

* 그것은 * 유용 할 수 있습니다 정확히 려

@projects = Project.find(:all, :includes => :user) 
@projects = Project.find(:all, :include => [{:association1 => [:associationA, :associationB, ....]}]