ActiveModel: 모델 모듈의 initialize 방법은 무엇입니까
개시하다
ActiveModel:include에 모델 추가
실례를 생성할 때 실례 변수를 간단하게 실례 변수에 대입하는 것이 아니라 설정 방법을 통해 대입하는 것을 알 수 있다.
# initializeメソッドを作成する場合
class User
attr_reader :name
def initialize(attributes = {})
@name = attributes[:name]
end
def name=(name)
@name = "#{name}君"
end
end
User.new(name: "俺")
=> #<User:0x00007f8c42d26b28 @name="俺">
# ActiveModel::Modelをincludeする場合
class User
include ActiveModel::Model
attr_reader :name
def name=(name)
@name = "#{name}君で〜す"
end
end
User.new(name: "俺")
=> #<User:0x00007f8c52d93150 @name="俺君で〜す">
그럼 이번에는ActiveModel::모델include에서 호출된 initialize 방법을 조사합니다.ActiveModel::Model
# rails/activemodel/lib/active_model/model.rb
module ActiveModel
..(省略)..
module Model
include ActiveModel::AttributeAssignment
..(省略)..
def initialize(attributes = {})
assign_attributes(attributes) if attributes
super()
end
end
end
rails/model.rb initialize 방법,assignattributes라는 방법이 호출되었습니다.이 방법은 Active Model::Attribute Assignment 모듈에 포함되어 있습니다.
assign_attributes 방법
# rails/activemodel/lib/active_model/attribute_assignment.rb
module ActiveModel
module AttributeAssignment
include ActiveModel::ForbiddenAttributesProtection
def assign_attributes(new_attributes)
# new_attributesがeach_pairメソッドを持たなければ(= hashでなければ)エラー
unless new_attributes.respond_to?(:each_pair)
raise ArgumentError, "When assigning attributes, you must pass a hash as an argument, #{new_attributes.class} passed."
end
return if new_attributes.empty?
# sanitize_for_mass_assignmentはマスアサインメントの際の許可に関するメソッドで、
# インスタンス生成時にhashをそのまま入れる場合は関係ないので今回は省略します
_assign_attributes(sanitize_for_mass_assignment(new_attributes))
end
alias attributes= assign_attributes
private
def _assign_attributes(attributes)
attributes.each do |k, v|
_assign_attribute(k, v)
end
end
def _assign_attribute(k, v)
setter = :"#{k}="
if respond_to?(setter)
public_send(setter, v)
else
raise UnknownAttributeError.new(self, k.to_s)
end
end
end
end
rails/attribute_assignment.rb assign_attributes 방법 중assign_이른바 attributes의 privete 방법이 호출되었다는 것을 알 수 있다assign_attribute방법public_send 메서드에서 보듯이setter방법이라고 부른다.
# public_methodでメソッドを呼び出す例
class Child
def greeting(name)
p "おはようございます、#{name}さん!"
end
end
Child.new.public_send("greeting", "太郎")
=> "おはようございます、太郎さん!"
에서 알 수 있듯이 ActiveModel:::Model은include와 initialize 방법에서 Senter 방법이라고 불린다.include가 아니라 코드를 직접 가지고 있으면 다음과 같이 됩니다(오류 처리 등 생략)
class Person
attr_reader :name
def initialize(attributes = {})
assign_attributes(attributes) if attributes
end
def name=(name)
@name = "#{name}君"
end
private
def assign_attributes(attributes)
_assign_attributes(attributes)
end
def _assign_attributes(attributes)
attributes.each do |k, v|
_assign_attribute(k, v)
end
end
def _assign_attribute(k, v)
setter = :"#{k}="
if respond_to?(setter)
public_send(setter, v)
else
raise UnknownAttributeError.new(self, k.to_s)
end
end
end
Person.new(name: "太郎")
=> #<Person:0x00007f8c52b22a60 @name="太郎君">
Reference
이 문제에 관하여(ActiveModel: 모델 모듈의 initialize 방법은 무엇입니까), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://zenn.dev/akhmgc/articles/79015b15a9301a텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)