2014-02-26 1 views
10

Ruby on Rails에서 모델에서 self.attribute와 attribute를 사용하는 것의 차이점은 무엇입니까?모델에서 self.attribute와 attribute를 사용하는 것과 다른 점은 무엇입니까?

이 예에서는 my_attr이 데이터베이스에 저장된 사용자의 특성이라고 가정합니다.

class User < ActiveRecord::Base 
    def do_something! 
    self.my_attr = 123 
    end 

    def do_another_thing! 
    my_attr = 456 
    end 
end 
+0

'self'를 사용하면 같은 이름의 로컬 변수와 잠재적 인 이름 충돌이 발생하는 것을 막을 수 있습니다. –

답변

9

다른 점은 하나는 작동하고 다른 하나는 의도하지 않는 것입니다.

두 번째 버전은 아무 것도하지 않습니다. self.my_attr = 123을 호출하는 것과 동일하지 않고 대신 my_attr이라는 로컬 변수를 만들고이를 123으로 설정 한 다음 메서드가 반환 될 때이를 throw합니다. 어떤 식 으로든 모델의 my_attr 값에 영향을 미치지 않습니다. 당신이 액세스 객체에 정의 된 방법을 원하는 경우

class User < ActiveRecord::Base 
    def do_another_thing! 
    my_attr = 456 

    puts self.my_attr # nil (or whatever value it was before) 
    end 
end 

반대로, 당신은 (그리고 should)는 self를 생략 할 수 있습니다, 이것은 레일 질문 아니라고

class User 
    def name=(value) 
    @name = value 
    end 

    def name 
    @name 
    end 

    def age=(value) 
    @age = value 
    end 

    def age 
    @age 
    end 

    def do_something 
    self.name = "bob" # self is required 
    puts name # bob 

    age = 47 # @age is unaffected 
    age # nil 
    end 
end 

주, 그것은 루비 질문입니다. Rails 관련 코드는 여기에 없으며,이 동작은 Ruby의 구문이 작동하는 방법의 일부입니다.

+1

좋습니다, 감사합니다. 이름을 가져올 때 self.name을 사용하지 말고 이름을 설정하려면 self.name을 사용하는 것이 좋습니다. 일관성을 위해 두 경우 모두에서 self.name을 사용하고자한다고 생각합니다. –

+0

@SomeGuy [합의 표준] (https://github.com/bbatsov/ruby-style-guide#no-self-unless-required)이므로 – meagar

0

do_something! 인스턴스 메소드입니다. 그래서 여기에 self는 User 인스턴스이고, my_attr =은 User 인스턴스의 메서드입니다. 이 함수는 사용자 인스턴스 변수 @may_attr에 값을 할당하는 것입니다.

"do_another_thing!"에서 my_attr은 방금 선언 한 변수가 될 수 있습니다.

+0

사실이 아닙니다. 'users' 테이블에'my_attr' 컬럼이 있다고 가정하면,'self.my_attr = ...'의 효과는'@ my_attr'을 설정하는 것이 아닙니다. – meagar

0

이 경우에는 차이점이 없습니다. 그러나이 방법 정의에 지역 변수가 있다고 가정 :

def do_something! 
    self.my_attr = 123 
end 

def do_another_thing!(my_attr) 
    puts "my_attr is #{my_attr}" 
    puts "self.my_attr is #{self.my_attr}" 
end 

do_something!   
do_another_thing!(456) 

그런 다음 출력이

my_attr is 456 
self.my_attr is 123 

self 객체를 나타내는 것입니다. self에서 메서드를 호출하면 해당 개체에서 메서드를 특히 호출합니다.

4

일반적인 규칙은 당신이 어떤 속성에 값을 할당하여 자체를 수정하는 때마다,이다는 명시 적으로

self.first_name = 'Prasad' #if self isnt used, it will create a local variable. 

'자기'를 사용하고 해당 속성을 참조하는 (그러나 수정되지 않음)하는 경우, 사용하는 '자기를 해달라고 '

def name 
    name.camelize 
end 

UPDATE ---- -----

우리가 어떤 속성을 액세스 할 때마다 그 특성에 대한 게터 (리더) 및 설정 부 (작가) 방법이 개발되면, 루비 확인할 것 그렇지 않은가.

위의 경우 (속성에 값을 할당 할 때) 속성에 직접 액세스하지 않고 속성에 값을 내부적으로 할당하는 설정자에게 값을 전달합니다.

2.1.0p0 :008 > User.first.first_name 
=> "Prasad" 
2.1.0p0 :009 > (User.first.methods - Object.methods).include? :first_name 
=> true 
2.1.0p0 :010 > (User.first.methods - Object.methods).include? :first_name= 
=> true 

당신은 어떤 모델

def some_name 
    first_name = 'Some name' 
    puts self.first_name 
    self.first_name = 'Random Username' 
    puts self.first_name 
end 

하는 방법을 추가하여 시도하고 콘솔을 다시로드 할 수

2.1.0p0 :017 > User.first.some_name 
Prasad 
Random Username 
=> nil 
+0

@muistooshort가 대답에 답변을 추가했습니다. –

0

루비의 키워드 자체는 현재에 액세스 할 수 있습니다 object - 현재의 메세지를 수신하고있는 오브젝트

따라서 은 current object's attribute을 말합니다. 여기에서 간단히 attributescope입니다.

자세한 내용은 self을 참조하십시오.

관련 문제