루비 온 레일즈에서 세터 방법을 재정의하는 올바른 방법은 무엇입니까?
저는 Rails 3.2.2에서 Ruby를 사용하고 있는데, 다음이 myclass 속성에 대한 setter 메서드를 재정의하는 "적절한"/"올바른"/"확실한" 방법인지 알고 싶습니다.
attr_accessible :attribute_name
def attribute_name=(value)
... # Some custom operation.
self[:attribute_name] = value
end
위의 코드는 예상대로 작동하는 것 같습니다.하지만, 위의 코드를 사용함으로써 앞으로 제가 문제가 생기거나 적어도 Ruby on Rails에 대해 "예상해야 하는"/"발생할 수 있는" 문제가 있는지 알고 싶습니다.만약 그것이 세터 방법을 무시하는 올바른 방법이 아니라면, 올바른 방법은 무엇입니까?
참고: 코드를 사용하는 경우
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일
이제 레일즈 설명서에서도 다음을 사용할 것을 제안합니다.super
다음과 같이:
class Model < ActiveRecord::Base
def attribute_name=(value)
# custom actions
###
super(value)
end
end
===========================================================================
원답
모델을 통해 액세스하는 동안 테이블 열에 대한 세터 메서드를 재정의하려면 이 방법을 사용합니다.
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
레일즈 문서에서 기본 접근자 재정의를 참조하십시오.
따라서 첫 번째 방법은 Ruby on Rails 모델에서 열 설정자를 재정의하는 올바른 방법입니다.이러한 접근기는 테이블의 열에 모델의 속성으로 액세스할 수 있도록 레일즈에서 이미 제공합니다.이것을 ActiveRecord ORM 매핑이라고 합니다.
또한 모델의 맨 위에 있는 것은 액세스 장치와 아무런 관련이 없습니다.기능이 완전히 다릅니다(이 질문 참조).
그러나 순수한 Ruby에서 클래스에 대한 접근자를 정의하고 세터를 재정의하려면 다음과 같은 인스턴스 변수를 사용해야 합니다.
class Person
attr_accessor :name
end
class NewPerson < Person
def name=(value)
# do something
@name = value
end
end
이것은 일단 당신이 그것을 알게 되면 이해하기 더 쉬울 것입니다.attr_accessor
그렇습니다. 코드는attr_accessor :name
이 두 가지 방법(게터 및 세터)에 해당합니다.
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
참고: 레일 4의 새 고객의 경우 모델에 atr_accessible을 지정할 필요가 없습니다.대신 permit 방법을 사용하여 컨트롤러 수준에서 속성을 화이트리스트에 추가해야 합니다.
(적어도 ActiveRecord 관계 컬렉션의 경우) 다음 패턴이 작동한다는 것을 알게 되었습니다.
has_many :specialties
def specialty_ids=(values)
super values.uniq.first(3)
end
(전달된 배열에서 중복되지 않는 처음 3개의 항목을 가져옵니다.)
용사를 합니다.attr_writer
:sys_namessetterattr_writer 파일. setter_name
def attribute_name=(value)
# manipulate value
# then send result to the default setter
super(result)
end
언급URL : https://stackoverflow.com/questions/10464793/what-is-the-right-way-to-override-a-setter-method-in-ruby-on-rails
'programing' 카테고리의 다른 글
ugettext_lazy는 언제 사용해야 합니까? (0) | 2023.06.06 |
---|---|
Android 도구 모음 센터 제목 및 사용자 정의 글꼴 (0) | 2023.06.01 |
SQL Server 연결 문자열을 설정하려면 어떻게 해야 합니까? (0) | 2023.06.01 |
Angular.copy의 Angular.copy에 대한 대안은 무엇입니까? (0) | 2023.06.01 |
루비에서 'continue'와 유사한 .each 루프에서 루프를 건너뛰려면 어떻게 해야 합니까? (0) | 2023.06.01 |