class UserTweet
include Mongoid::Document
field :user_desc, type:String
field :type, type:String
field :tweet_uuid, type:String
belongs_to :tweet
scope :tweet_uuid_exists, ->(tweet_uuid){ where(tweet_uuid: tweet_uuid) }
scope :type_exists, ->(type){ where(type: type) }
scope :user_desc_exists, ->(user_desc){ where(user_desc: user_desc) }
def self.params=(params)
@params = params
end
def self.params
@params
end
def self.criteria
UserTweet.where(user_desc: params[:user_desc],
type: params[:type],
tweet_uuid: params[:tweet_uuid])
end
def self.save
if !criteria.exists?
tweet = Tweet.find_by(uuid: params[:tweet_uuid])
tweet.user_tweets.create(Hash[params])
_success
else
_fail('already requested')
end
end
def self.delete
if criteria.exists?
criteria.delete
_success
else
_fail('resource not exists')
end
end
private
def self._success
{:result => 1, :msg => 'success'}
end
private
def self._fail(msg)
{:result => 0, :msg => msg}
end
end
위의 코드를 보시면 아시겠지만 params의 setter/getter 함수에서 인스턴스 변수를 사용했습니다. 실제 컨트롤러에서는 다음과 같이 호출했습니다.
def set_params
UserTweet.params = params.except(:action, :controller)
end
그럼 이제부터 model에서 instance variable이 갖는 의미를 알아보도록 하겠습니다.먼저 @의 의미부터 알아봐야 될 것 같습니다.
만약 variable, @variable 2 가지의 변수가 있다고 해보겠습니다.
각각의 변수가 가지는 의미는 다음과 같습니다.
variable : 지역변수, 현재 블락에서만 사용 가능하다.
@variable : 인스턴스 변수 클래스내의 모든 메소드에서 사용 가능하다.
테스트를 해보겠습니다. 저 위의 코드에서 실제로 @params를 제거하면 "undefined method" 에러가 발생합니다. 실제로 attr_accessor 또한 인스턴스 gettter/setter를 생성시키므로 attr_accessor을 명시한다고 해도 같은 에러가 발생합니다. 따라서 params의 getter/settter에서 params 인스턴스 변수를 생성시킴으로써 모든 메소드에서 해당 변수에 접근할 수 있게 됩니다.
그럼 model에서 인스턴스 변수가 갖는 의미를 알아보겠습니다. model에서도 같은 의미를 사용될 수 있는데 저렇게 사용되면 각 객체의 변수라기 보다는 클래스의 변수라고 보면 됩니다. 그렇기 때문에 위 처럼 사용해도 문제가 없습니다.
그럼 상단의 코드를 좀 더 깔끔하게 수정해보겠습니다.
class UserTweet class << self
attr_accessor :params
endparams에 대한 getter/settter를 제거하고 위와 같이 변경하였습니다.
저렇게 변경해도 에러가 발생하지 않고 상단코드와 똑같은 의미를 가지게 됩니다.
그럼 저 코드를 분석해 보도록 하겠습니다.
상단의 코드는 params attribute_accessor를 인스턴스 레벨이 아닌 클래스 레벨에 추가하게 됩니다.
class << self는 self 싱글턴 클래스를 가져오게 되고 그러므로 self 안에 정의된 attr_accessor이 self 객체에 재 정의됩니다. 이 문법은 특히 메타클래스라 부릅니다. 그러므로 이 문법은 상단의 gettter/setter와 일치하게 됩니다.
감사합니다.
댓글 없음:
댓글 쓰기