attr_accessor가 Ruby on Rails 의이 모델의 기존 변수를 거부하는 이유는 무엇입니까?
-
11-09-2019 - |
문제
나는 최근에 이것에 물렸고, 이런 일이 일어나기 위해 무슨 일이 일어나고 있는지 정확하게 아는 것이 유용 할 것이므로 다른 사람들은이 실수를 피합니다.
SO와 같은 스키마가있는 모델 사용자가 있습니다.
create_table "users", :force => true do |t|
t.string "user_name"
t.string "first_name"
t.string "last_name"
t.string "email"
t.string "location"
t.string "town"
t.string "country"
t.string "postcode"
t.boolean "newsletter"
클래스 user.rb에는 세 가지 방법에 대한 attr_accessor가 있습니다.
class User < ActiveRecord::Base
# lots of code
attr_protected :admin, :active
# relevant accessor methods
attr_accessor :town, :postcode, :country
end
이제 내 사용자 컨트롤러에서 다음 방법이있는 경우 :
def create
@user = User.new params[:user]
end
이 Params Hash의 내용으로 새 사용자를 만들려고 할 때 :
--- !map:HashWithIndifferentAccess
# other values
country: United Kingdom
dob(1i): "1985"
dob(2i): "9"
dob(3i): "19"
town: london
반환 된 객체에는 비어있는 문자열이 있습니다 country
, town
그리고 우편 번호 postcode
그렇게 값.
(rdb:53) y user1
--- !ruby/object:User
attributes:
# lots of attributes that aren't relevant for this example, and are filled in okay
postcode:
country:
town:
attr_accessor 메소드가 활성 레코드의 기존 액세서 메소드를 거부하고 있다고 말할 수 있습니다. 왜냐하면 내가 꺼내면 모든 것이 잘 작동하기 때문에 솔루션은 상당히 간단하기 때문입니다.
하지만 무엇 여기에 정확히 일어나고 있습니까?
나는 여기에서보고있다 활성 레코드를위한 Rails API 문서, 그리고 여기에 루비 자신의 문서에 대한 문서 attr_accessor
,하지만 나는 여전히 방법에 대해 약간 흐릿합니다 attr_accessor
여기에서 물건을 깨고 있습니다.
다른 가난한 영혼을 막기 위해 약간의 빛을 흘릴 수 있습니까?
해결책
클래스에 Att_Accessor를 추가하면 사용자#우편 번호 및 사용자#홍보 = (예 : 사용자#우편 번호 및 사용자#홍보 =)의 두 가지 메소드가 정의됩니다.
액세서의 이름이 모델 속성의 이름과 같으면 상황이 깨지지 않습니다 (조심하지 않은 경우). 모델에 속성을 할당하면 사용자#홍보 = 호출되고 귀하의 경우에는 아무것도하지 않습니다.
@postcode = value
따라서 값은 인스턴스 변수에 저장되며 속성 해시에 표시되지 않습니다.
반면, 일반 시나리오에서는 (액세서가없는) Method_missing으로 이동하여 결국에는 다음과 같은 것을 트리거합니다.
write_attribute(:postcode, value)
그러면 모델의 속성에 나타납니다. 그것이 말이되기를 바랍니다.
다른 팁
처음에 당신이 사용하는 이유 attr_accessor :town, :postcode, :country
? Active Record에는 Setter/Getter 방법이 있습니다. 그 줄에 그 줄을 떨어 뜨리십시오. 일이 작동해야합니다.
사용하고 싶을 수도 있습니다 attr_accessible
ActiveRecord 모델에서 속성의 질량 할당을 가능하게합니다. 당신은 필요하지 않습니다 attr_accessor
getters / setters는 이미 모델 속성에 대해 정의되어 있습니다.