복붙노트

[RUBY-ON-RAILS] 루비 온 레일즈의 setter 메소드를 오버라이드 (override) 할 수있는 권리 방법은 무엇입니까?

RUBY-ON-RAILS

루비 온 레일즈의 setter 메소드를 오버라이드 (override) 할 수있는 권리 방법은 무엇입니까?

나는 레일 3.2.2에 루비를 사용하고 난 다음에 내 클래스 속성에 대한 setter 메소드를 오버라이드 (override) 할 수있는 "적절한"/ "올바른"/ "확인"방법이 있는지 알고 싶습니다.

attr_accessible :attribute_name

def attribute_name=(value)
  ... # Some custom operation.

  self[:attribute_name] = value
end

예상대로 위의 코드는 작동하는 것 같다. 그러나, 나는 레일에 루비와 "일어날 수"/ 미래에 내가 "나는 기대한다"무엇이 문제, 적어도 문제가 있거나 것, 위의 코드를 사용하여 있는지 알고 싶습니다. 즉 세터 메소드를 오버라이드 (override) 할 수있는 올바른 방법이없는 경우, 올바른 방법은 무엇입니까?

참고 : 나는 코드를 사용하는 경우

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

해결법

  1. ==============================

    1.================================================== ========================= 업데이트 : 2017년 7월 19일

    ================================================== ========================= 업데이트 : 2017년 7월 19일

    이제 레일 문서는이 같은 슈퍼 사용하도록 제안한다 :

    class Model < ActiveRecord::Base
    
      def attribute_name=(value)
        # custom actions
        ###
        super(value)
      end
    
    end
    

    ===========================================================================

    원래 대답

    당신이 모델을 통해 액세스하는 동안 테이블의 열에 대한 setter 메소드를 오버라이드 (override) 할 경우,이 할 수있는 방법입니다.

    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
    

    레일 문서에 기본 접근 재정을 참조하십시오.

    그래서, 당신의 첫 번째 방법은 루비 온 레일즈의 모델에 열 세터를 오버라이드 (override)하는 올바른 방법이다. 이러한 접근은 이미 모델의 속성으로 테이블의 컬럼에 액세스하기 위해 레일에 의해 제공됩니다. 이것은 우리가 액티브 ORM 매핑을 부르는 것이다.

    또한 모델의 상단에있는 attr_accessible가 접근과는 아무 상관이 없다는 것을 명심하십시오. 그것은 완전히 다른 functionlity있다 (이 질문을 참조)

    당신이 클래스에 대한 접근을 정의 세터를 오버라이드 (override) 할 경우 그러나 순수 루비에, 당신은이 같은 인스턴스 변수의 사용을해야합니다 :

    class Person
      attr_accessor :name
    end
    
    class NewPerson < Person
      def name=(value)
        # do something
        @name = value
      end
    end
    

    당신이 attr_accessor가 무엇을 알고 한 번이 이해하기 쉬울 것이다. 코드 attr_accessor : 이름은 이러한 두 가지 방법에 해당합니다 (getter 및 setter)

    def name # getter
      @name
    end
    
    def name=(value) #  setter
      @name = value
    end
    

    그 방법 내부와 동일한 방법 ATTRIBUTE_NAME의 =를 호출로 무한 루프가 발생할 수 있기 때문에 두 번째 방법은 실패합니다.

  2. ==============================

    2.슈퍼 키워드를 사용 :

    슈퍼 키워드를 사용 :

    def attribute_name=(value)
      super(value.some_custom_encode)
    end
    

    반대로, 독자를 오버라이드 (override) :

    def attribute_name
      super.some_custom_decode
    end
    
  3. ==============================

    3.이어 4 레일

    이어 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의 새로운 올 사람을 위해 당신은 모델에서 attr_accessible 지정할 필요가 없습니다. 대신 흰색 - 목록에 허가 방법을 사용하여 컨트롤러 수준에서 속성이 있습니다.

  4. ==============================

    4.나는 것으로 나타났습니다 다음과 같은 패턴 작업 (액티브 관계 컬렉션에 대한 최소한) :

    나는 것으로 나타났습니다 다음과 같은 패턴 작업 (액티브 관계 컬렉션에 대한 최소한) :

    has_many :specialties
    
    def specialty_ids=(values)
      super values.uniq.first(3)
    end
    

    (이 전달 어레이의 제 3 비 중복 엔트리를 잡는다.)

  5. ==============================

    5.덮어 쓰기 세터에 attr_writer 사용 attr_writer : ATTRIBUTE_NAME

    덮어 쓰기 세터에 attr_writer 사용 attr_writer : ATTRIBUTE_NAME

      def attribute_name=(value)
        # manipulate value
        # then send result to the default setter
        super(result)
      end
    
  6. from https://stackoverflow.com/questions/10464793/what-is-the-right-way-to-override-a-setter-method-in-ruby-on-rails by cc-by-sa and MIT license