2013년 12월 12일 목요일

[ROR] attr_accessor, attr_accessible의 개념 및 차이

안녕하세요 belhyun입니다.
rails의 model을 보게되면, attr_accessor, attr_accessible이가 자주 나타납니다.
이름이 비슷하여 헷갈릴 수 있는데 이에 대한 개념을 정리해 보도록 하겠습니다.
먼저 그 개념부터 언급하도 넘어가겠습니다.

attr_accessible : 이 속성은 대량으로 업데이트 되는 것이 허용된 속성의 whitelist(가능한 리스트로 생각하시면 됩니다.)를 기술합니다. 이 속성의 주요 목적은 mass assignment에 의한 공격에 대한 방어입니다.

attr_accessor : 이 속성은 gettter/setter를 생성시키는 짧은 코드입니다.

다음과 같은 테이블을 가정해보겠습니다.
CREATE TABLE users (
  firstname string,
  lastname string
  role string
);
Model의 형태는 다음과 같을 것입니다.
class User < ActiveRecord::Base

end
만약 특정 user의 정보를 업데이트 하고자 원할 경우 다음과 같이 할 수 있습니다.
def update
    @user = User.find_by_id(params[:id])
    @user.firstname = params[:user][:firstname]
    @user.lastname = params[:user][:lastname]

    if @user.save
        # Use of I18 internationlization t method for the flash message
        flash[:success] = t('activerecord.successful.messages.updated', :model => User.model_name.human)
    end

    respond_with(@user)
end
하지만 위의 방법은 너무 복잡합니다. 이때, attr_accessible을 기술하고 간단히 업데이트 해보겠습니다.
class User < ActiveRecord::Base

  attr_accessible :firstname, :lastname
end

def update
    @user = User.find_by_id(params[:id])

    if @user.update_attributes(params[:user])
        # Use of I18 internationlization t method for the flash message
        flash[:success] = t('activerecord.successful.messages.updated', :model => User.model_name.human)
    end

    respond_with(@user)
end
여기서 주목할 점은 role이 빠져있다는 점입니다. params[:user]로 업데이트 한다고 해도(mass assignment), role은 변경되지 않습니다. 왜냐하면 attr_accessible에 기술하지 않았기 때문입니다. 따라서 다음과 같은 추가코드가 필요합니다.
@user.role = DEFAULT_ROLE
다음은 attr_accessor에 대해서 알아보겠습니다. 만약 다음과 같은 코드를 기술했다고 해보겠습니다.
class User < ActiveRecord::Base

  attr_accessible :firstname, :lastname
  attr_accessor :test

end
위의 코드로 인해 test에 대한 getter/setter 메소드가 생성됩니다. 실제 위 코드는 아래와 동일합니다.
def test
  @test
end
def test=(value)
  @test = value
end
따라서 user.test의 속성을 정의할 수 있게 됩니다. 이 속성은 실제 DB 컬럼은 아니기 때문에 user.save등으로 저장한다고 해도 실제 저장되지는 않습니다. 감사합니다.

댓글 없음:

댓글 쓰기