ActiveRecord 속성 메소드 대체


150

내가 말하는 것에 대한 예 :

class Person < ActiveRecord::Base
  def name=(name)
    super(name.capitalize)
  end
  def name
    super().downcase  # not sure why you'd do this; this is just an example
  end
end

이것은 작동하는 것처럼 보이지만 ActiveRecord :: Base docs 에서 속성 메소드를 재정의하는 섹션을 읽었 으며 read_attributeand write_attribute메소드를 사용하는 것이 좋습니다 . 위의 예에서 내가하고있는 일에 문제가 있다고 생각했습니다. 그렇지 않으면 왜 속성 메소드를 재정의하는 "올바른 방법"으로 이러한 메소드를 축복합니까? 그들은 또한 더 못생긴 관용구를 강요하고 있기 때문에 좋은 이유가 있어야합니다 ...

내 진짜 질문 :이 예제에 문제가 있습니까?

답변:


211

Gareth의 의견을 반향 ... 귀하의 코드는 작성된대로 작동하지 않습니다. 다음과 같이 다시 작성해야합니다.

def name=(name)
  write_attribute(:name, name.capitalize)
end

def name
  read_attribute(:name).downcase  # No test for nil?
end

정확히 내가 필요한 것. 고마워 Aaron.
bong

18
이것은 더 이상 사실이 아닙니다. 슈퍼 또는 이것은 지금 작동합니다. 그러나 해시 표기법을 테스트하지 않았습니다.
heartpunk

2
레일 3에서, Aaron에 의해 여기에 지정된 리더 방법이 작동하지만, 원래 포스터가 지정한 이름 (super에 이름을 제공함)은 잘 작동하며 IMHO는 Aaron이 제안한대로 속성을 수동으로 작성하는 것보다 더 깨끗합니다.
Batkins

1
아래에서 mipadi가 제공 한 해시 방법을 테스트했으며 매력처럼 작동합니다 (Rails v 3.2.6)
almathie

정답이 아닙니까? @Aaron에게 감사드립니다.
Sadiksha Gautam

94

Aaron Longwell의 답변에 대한 확장으로 "해시 표기법"을 사용하여 재정의 된 접근 자와 뮤 테이터가있는 속성에 액세스 할 수도 있습니다.

def name=(name)
  self[:name] = name.capitalize
end

def name
  self[:name].downcase
end

해시 표기법은 효과가 있지만 self.attribute3.2.16에서 스택을 날려 버립니다.
jrhorn424

이는 ||=기본 설정을 지원한다는 장점이 있습니다 .def name; self[:name] ||= 'anon'; end
Paul Cantrell

나 에게이 해시 표기법이 효과가 있습니다. 그러나 나는 그것이 왜 작동하는지 이유를 모른다. 누군가 설명 할 수 있습니까?
radiantshaw


-1

속성 오버라이드가 super와 함께 작동하도록하는 레일 플러그인이 있습니다. github에서 찾을 수 있습니다 .

설치하기 위해서:

./script/plugin install git://github.com/chriseppstein/has_overrides.git

쓰다:

class Post < ActiveRecord::Base

  has_overrides

  module Overrides
    # put your getter and setter overrides in this module.
    def title=(t)
      super(t.titleize)
    end
  end
end

일단 당신이 그 일을 작동하면 :

$ ./script/console 
Loading development environment (Rails 2.3.2)
>> post = Post.new(:title => "a simple title")
=> #<Post id: nil, title: "A Simple Title", body: nil, created_at: nil, updated_at: nil>
>> post.title = "another simple title"
=> "another simple title"
>> post.title
=> "Another Simple Title"
>> post.update_attributes(:title => "updated title")
=> true
>> post.title
=> "Updated Title"
>> post.update_attribute(:title, "singly updated title")
=> true
>> post.title
=> "Singly Updated Title"
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.