Ruby on Rails에서 setter 메소드를 재정의하는 올바른 방법은 무엇입니까?
Ruby on Rails 3.2.2를 사용하고 있으며 다음이 내 클래스 속성의 setter 메소드를 대체하는 "적절한"/ "정확한"/ "확실한"방법인지 알고 싶습니다.
attr_accessible :attribute_name
def attribute_name=(value)
... # Some custom operation.
self[:attribute_name] = value
end
위의 코드는 예상대로 작동하는 것 같습니다. 그러나 위의 코드를 사용하여 앞으로 문제가 발생하는지 또는 최소한 Ruby on Rails에서 "예상해야 할"/ "어떻게 발생할 수있는"문제가 있는지 알고 싶습니다 . 이것이 setter 메소드를 재정의하는 올바른 방법이 아닌 경우 올바른 방법은 무엇입니까?
참고 : 코드를 사용하면
attr_accessible :attribute_name
def attribute_name=(value)
... # Some custom operation.
self.attribute_name = value
end
다음과 같은 오류가 발생합니다.
SystemStackError (stack level too deep):
actionpack (3.2.2) lib/action_dispatch/middleware/reloader.rb:70
===================================================== ========================= 업데이트 : 2017 년 7 월 19 일
이제 Rails 문서 도 super다음과 같이 사용하도록 제안합니다 .
class Model < ActiveRecord::Base
def attribute_name=(value)
# custom actions
###
super(value)
end
end
===================================================== ==========================
원래 답변
모델을 통해 액세스하는 동안 테이블의 열에 대한 setter 메소드를 대체하려는 경우이를 수행하는 방법입니다.
class Model < ActiveRecord::Base
attr_accessible :attribute_name
def attribute_name=(value)
# custom actions
###
write_attribute(:attribute_name, value)
# this is same as self[:attribute_name] = value
end
end
Rails 설명서에서 기본 접근 자 재정의를 참조하십시오 .
따라서 첫 번째 방법은 Ruby on Rails 모델에서 열 설정자를 재정의하는 올바른 방법입니다. 이러한 접근자는 모델의 속성으로 테이블의 열에 액세스하기 위해 Rails에서 이미 제공합니다. 이것을 우리는 ActiveRecord ORM 매핑이라고합니다.
또한 attr_accessible모델 상단의 접근자는 접근 자와 관련이 없습니다. 그것은 완전히 다른 기능을 가지고 있습니다 ( 이 질문을보십시오 )
그러나 순수 루비에서 클래스에 대한 접근자를 정의하고 세터를 재정의하려면 다음과 같이 인스턴스 변수를 사용해야합니다.
class Person
attr_accessor :name
end
class NewPerson < Person
def name=(value)
# do something
@name = value
end
end
무엇을 알면 이해하기가 더 쉬울 것 attr_accessor입니다. 코드 attr_accessor :name는이 두 가지 방법 (getter 및 setter)과 동일합니다.
def name # getter
@name
end
def name=(value) # setter
@name = value
end
또한 두 번째 메소드는 해당 메소드 attribute_name=내 에서 동일한 메소드를 호출 할 때 무한 루프가 발생하기 때문에 실패합니다 .
super키워드를 사용하십시오 :
def attribute_name=(value)
super(value.some_custom_encode)
end
반대로 독자를 무시하려면 다음을 수행하십시오.
def attribute_name
super.some_custom_decode
end
레일 4
테이블에 나이 속성 이 있다고 가정 해 봅시다.
def age=(dob)
now = Time.now.utc.to_date
age = now.year - dob.year - ((now.month > dob.month || (now.month == dob.month && now.day >= dob.day)) ? 0 : 1)
super(age) #must add this otherwise you need to add this thing and place the value which you want to save.
end
Note: For new comers in rails 4 you don't need to specify attr_accessible in model. Instead you have to white-list your attributes at controller level using permit method.
I have found that (at least for ActiveRecord relationship collections) the following pattern works:
has_many :specialties
def specialty_ids=(values)
super values.uniq.first(3)
end
(This grabs the first 3 non-duplicate entries in the array passed.)
Using attr_writer to overwrite setter attr_writer :attribute_name
def attribute_name=(value)
# manipulate value
# then send result to the default setter
super(result)
end
'Programming' 카테고리의 다른 글
| jQuery를 사용하여 요소를 선택하려면 어떻게해야합니까? (0) | 2020.05.24 |
|---|---|
| 서브 클립 스 svn : ignore (0) | 2020.05.24 |
| "일등석"개체 란 무엇입니까? (0) | 2020.05.23 |
| Eclipse 용 Bash 스크립트 플러그인? (0) | 2020.05.23 |
| Java에서 컴퓨터의 CPU, 메모리 및 디스크 사용량을 어떻게 모니터링합니까? (0) | 2020.05.23 |