2009-11-05 4 views
13

어쩌면 일부 루비 전문가가 save()를 호출 할 때 activerecord가 삽입 또는 업데이트를 수행하는 방법에 대해 알 수 있습니다. 그것 뒤에있는 논리는 무엇입니까? 기본 키가 비어 있는지 확인하고, 업데이트가 아닌 경우 삽입을 수행합니까?activerecord는 삽입 또는 업데이트를 어떻게 수행합니까?

+0

우수 질문. –

답변

23

나는 오히려 더 걸어 관통하지만 - 여전히-entirely- 쓸모-때 레일-3-제공 아웃 - 및 - 변경 - 모든 응답 : 레일에서 작동하는 방법

2.3 (일명 "오늘")

save가 012,349를 호출

def create_or_update 
    raise ReadOnlyRecord if readonly? 
    result = new_record? ? create : update 
    result != false 
end 

레코드가 읽기 전용 인 경우에만 오류가 발생합니다으로 당신은이 방법의 첫 번째 줄을 무시할 수 있습니다 (이것은 보통 아니지만, 경우의가있을 수 있습니다 조인) : 다음과 같습니다. 여기서 우리가 관심을 갖는 것은 메서드 내부의 두 번째 및 세 번째 행입니다.

두 번째 줄은 같이 정의된다 new_record?를 호출하십시오 initialize

# Returns true if this object hasn't been saved yet -- that is, a record for the object doesn't exist yet; otherwise, returns false. 
    def new_record? 
    @new_record || false 
    end 

그리고 변수 @new_record가 설정됩니다 (new 전화 initialize, 그리고 우리에게 새로운 객체를 제공, 여기에 몇 가지 배경 루비-FU) 메서드가 호출됩니다. 이 @new_record 경우

그래서 truecreate 전화 할게 그것이 거짓이라면 당신이 계신 우리에게 가져다 update 전화 할게, 내가 생각합니다.

또한 레코드를 찾으면 initialize을 호출하지 않으므로 @new_record을 설정하지 않습니다. 눈치 챘을 경우 new_record? 뒤에있는 코드는 @new_record || false이며 @new_record이 설정되지 않은 경우 false를 반환합니다.

예를 들어 Forum 레코드를 찾고 싶다고 가정하면 Forum.last입니다.

  1. 이 액티브에서 상속 Forum 클래스 :: 자료
  2. lastcallsfind 클래스 메소드에 last 메소드를 호출합니다.
  3. findcallsfind_last
  4. find_lastcallsfind_initial
  5. find_initialcalls
  6. find_everycallsfind_by_sql
  7. find_everyfind_by_sql 전화 instantiate

이 변경 사항을 따라 아무데도 @new_record이 설정되어 있으므로 find에 의해 얻은 기록은 새 기록이 아닙니다.

희망 사항을 이해하는 데 도움이됩니다.

+0

아주 좋은 대답과 나는 당신이 그것을 쓸 시간이 당신을 생각합니다. 또한 @nw_record를 false로 설정하는 것에 관심이 있습니까? 그것이 데이터베이스에서 레코드를 가져 오는 경우 찾기를 수행하면됩니까? – rip747

+0

메소드 찾기 체인으로 게시물을 업데이트했습니다. –

+0

어쨌든 "new_record"속성을 직접 수정 하시겠습니까? –

1

활성 레코드의 문서 here과 소스 코드 there을 확인하십시오.

+0

나는 워드 프로세서와 코드를 통해 읽고 있으며 내 머리를 감쌀 수 없습니다. – rip747

+0

당신도 마스터에 연결 중입니다. 아마 2.3을 사용하고있을거야. –

2

원칙적으로 new_record? 방법을 사용합니다.
이 메서드는 새 레코드이면 true를 반환하고 그렇지 않으면 false를 반환합니다.

사실 실제로 어렵지 않습니다.

  • 기존 레코드를 가져 오면 새로운 레코드가 아닙니다. 따라서 new_record?은 direcly false를 반환 할 수 있습니다.
  • 새 레코드 (Model.new)를 만들 때 new_record?이 true를 반환합니다. 새로운 기록입니다.
  • 새 레코드를 저장하면 더 이상 새 레코드가 아닙니다. 내부 변수 @new_record이 업데이트됩니다. new_record?은 더 이상 true를 반환하지 않습니다. 그것이 일어날 때

라인, ActiveRecord::Base로 이동하여 볼 수있는 2911

어떤 사람들이 말하는 "RTFM"하는 것이 괜찮 동안
self.id ||= new_id 

    @new_record = false 
    id 
    end 
+0

그가 2.3을 사용하고있을 때 마스터에 연결 중입니다. –

+0

그건 내 주장을 변경하지 않습니다. 하지만 어쨌든 링크를 업데이트했습니다. –

관련 문제