attr_accessor와 attr_accessible의 차이점


235

Rails에서 attr_accessor와 의 차이점은 무엇 attr_accessible입니까? 내 이해에서 using attr_accessor은 해당 변수에 대한 getter 및 setter 메서드를 만드는 데 사용되므로 Object.variableor 와 같은 변수에 액세스 할 수 있습니다 Object.variable = some_value.

나는 attr_accessible그 특정 변수를 외부 세계에 액세스 할 수 있도록 읽었습니다 . 누군가가 차이점을 말해 줄 수 있습니까?


4
attr_accessorgetter 및 setter 메소드를 생성하는 데 사용 하는 것이 맞습니다 . 꽤 포괄적 인 설명은 이전의 질문에 대한 내 대답을 참조하십시오 attr_accessible: stackoverflow.com/questions/2652907/...는 그 후 다른 특정 세부 사항을 필요로하는 경우 다음 질문을 업데이트합니다.
mikej 2016 년

2
당신은 상단의 대답에 따라 때문에, protected_attributes 보석을 사용하지 않는 attr_accessible는 더 이상 레일 4에서 지원되지 않습니다 stackoverflow.com/questions/17371334/... (2014 7월)
에머리

답변:


258

attr_accessorgetter와 setter를 만드는 Ruby 메소드입니다. attr_accessible는 대량 할당에 값을 전달할 수있는 Rails 메서드입니다. new(attrs)또는 update_attributes(attrs).

대량 할당은 다음과 같습니다.

Order.new({ :type => 'Corn', :quantity => 6 })

주문에 할인 코드가 있다고 상상할 수 있습니다 :price_off. 당신이 태그를하지 않으면 :price_off으로 attr_accessible그렇게 같이 할 수있는 악성 코드를 중지 :

Order.new({ :type => 'Corn', :quantity => 6, :price_off => 30 })

양식에 필드가없는 경우에도 :price_off모델에있는 경우 기본적으로 사용 가능합니다. 즉, 만들어진 POST는 여전히 설정할 수 있습니다. attr_accessible흰색을 사용하면 대량으로 할당 할 수있는 항목이 나열됩니다.


2
attr_accessibleRails 설명서에 없는 이유는 무엇 입니까? api.rubyonrails.org
Chloe

19
Rails4가 새로운 방식으로 작업하는 것처럼 보입니다. 이 답변보기 : stackoverflow.com/questions/17371334/…
Paul Rubel

1
강력한 매개 변수가 attr_accessible edgeguides.rubyonrails.org/…
Imran Ahmad

173

이 스레드와 Google의 많은 사람들이 attr_accessible대량으로 업데이트 할 수있는 속성의 화이트리스트 ( 동시에 객체 모델의 모든 속성을 동시에 지정) 를 지정하는 것이 매우 잘 설명 되어 있습니다. 이것은 주로 응용 프로그램을 보호하기위한 것입니다. "대량 할당"해적 공격.

이 내용은 공식 Rails 문서에서 설명합니다 : 대량 할당

attr_accessor클래스에서 setter 및 getter 메소드를 (빠르게) 작성하는 루비 코드입니다. 그게 다야.

이제 설명으로 누락 된 것은 데이터베이스 테이블이있는 (Rails) 모델 사이의 링크를 만들 때 모델에서 절대로 attr_accessorsetter 및 getter를 생성 할 필요가 없다는 것입니다. 테이블의 기록.

모델이 ActiveRecord::Base클래스의 모든 메소드를 상속하므로 기본 CRUD 액세서 (만들기, 읽기, 업데이트, 삭제)가 이미 정의되어 있기 때문 입니다. 여기는 공식 문서 인 Rails 모델기본 접근 자를 덮어 쓰는 방법에 설명되어 있습니다 ( "기본 접근 자 덮어 쓰기"장으로 스크롤 하십시오 ).

예를 들어, "firstname", "lastname"및 "role"이라는 세 개의 열을 포함하는 "users"라는 데이터베이스 테이블이 있습니다.

SQL 명령어 :

CREATE TABLE users (
  firstname string,
  lastname string
  role string
);

config.active_record.whitelist_attributes = true대량 할당 악용으로부터 응용 프로그램을 보호하기 위해 config / environment / production.rb에서 옵션을 설정했다고 가정했습니다 . 여기에 설명되어 있습니다 : 대량 할당

Rails 모델은 아래 모델과 완벽하게 호환됩니다.

class User < ActiveRecord::Base

end

그러나 양식의보기가 작동하려면 컨트롤러에서 사용자의 각 속성을 별도로 업데이트해야합니다.

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 internationalization 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

따라서 "highway"(대량 할당)를 사용하여 다음을 업데이트 할 수 있습니다.

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

"역할"속성을 attr_accessible목록에 추가 하지 않았습니다. 사용자가 관리자처럼 자신의 역할을 스스로 설정할 수 없기 때문입니다. 다른 특수 관리자보기에서이 작업을 직접 수행하십시오.

사용자보기에는 "역할"필드가 표시되지 않지만 해적은 params 해시에 "역할"을 포함하는 HTTP POST 요청을 쉽게 보낼 수 있습니다. 의 "역할"속성이 누락되면 attr_accessible응용 프로그램을 보호하는 것입니다.

아래처럼 자체적으로 user.role 속성을 수정할 수 있지만 모든 속성을 함께 사용할 수는 없습니다.

@user.role = DEFAULT_ROLE

도대체 왜 사용 attr_accessor하겠습니까?

사용자 양식에 users 테이블에 존재하지 않는 필드가 열로 표시되는 경우입니다.

예를 들어, 사용자보기에 "관리자에게 문의하십시오"필드가 표시되어 있다고 가정하십시오. 이 정보를 테이블에 저장하고 싶지 않습니다. Rails가 "crazy";-) 사용자가 구독했다는 경고 이메일을 보내려고합니다.

이 정보를 사용하려면 정보를 임시로 어딘가에 저장해야합니다. user.peekaboo속성 에서 복구하는 것보다 더 쉬운 방법은 무엇입니까 ?

따라서이 필드를 모델에 추가하십시오.

class User < ActiveRecord::Base

  attr_accessible :firstname, :lastname
  attr_accessor :peekaboo

end

따라서 user.peekaboo컨트롤러 어딘가에서 속성을 교육적으로 사용 하여 전자 메일을 보내거나 원하는 작업을 수행 할 수 있습니다.

ActiveRecord는 user.save모델에서이 이름과 일치하는 열이 표시되지 않으므로 테이블에 "peekaboo"속성을 저장 하지 않습니다.


48

attr_accessor같은 이름의 인스턴스 변수에 setter 및 getter 메소드를 제공하는 Ruby 메소드입니다. 따라서

class MyModel
  def my_variable
    @my_variable
  end
  def my_variable=(value)
    @my_variable = value
  end
end

attr_accessible 대량 할당에서 설정할 수있는 변수를 결정하는 Rails 방법입니다.

양식을 제출할 때 양식을 제출하면 MyModel.new params[:my_model]사람들이 원하지 않는 것을 제출할 수 없도록 조금 더 제어 할 수 있어야합니다.

당신은 할 수있는 attr_accessible :email누군가가 자신의 계정을 업데이트 할 때, 그들은 자신의 이메일 주소를 변경할 수 있도록. 그러나 attr_accessible :email, :salary양식 제출을 통해 급여를 설정할 수 있기 때문에 그렇게하지 않을 것 입니다. 다시 말해, 그들은 인상을 위해 길을 갈 수 있습니다.

이러한 종류의 정보는 명시 적으로 처리해야합니다. 양식에서 제거하는 것만으로는 충분하지 않습니다. 누군가 파이어 버그를 가지고 양식에 요소를 추가하여 급여 필드를 제출할 수 있습니다. 내장 컬을 사용하여 새 급여를 컨트롤러 업데이트 방법에 제출하고 해당 정보가 포함 된 게시물을 제출하는 스크립트를 작성할 수 있습니다.

그래서 attr_accessor매장 변수에 대한 방법을 만드는 방법에 대해, 그리고 attr_accessible질량 과제의 보안에 관한 것입니다.


2
코드 블록 뒤에 다음과 같은 오타가 있습니다.attr_accesible
Chubas

대단한 글을 쓰고, 나는 수업 예제를 좋아합니다. 에 대한 설명을 포함한 추가 (가짜) 보너스 포인트 :as!
Ian Vaughan

모델은 ActiveRecord :: Base에 의해 확장됩니다. class User < ActiveRecord::Base
Green

18

attr_accessor루비 코드이며 데이터베이스에 열이 없지만 양식에 필드를 표시하려고 할 때 사용됩니다. 이를 허용하는 유일한 방법은 attr_accessor :fieldname이 필드를 뷰 또는 모델 (원하는 경우 대부분의 경우 뷰)에서 사용할 수 있습니다.

다음 예제를 보자

class Address
    attr_reader :street
    attr_writer :street  
    def initialize
        @street = ""
    end
end

여기서는 액세스 목적으로 attr_reader( readable attribute ) 및 attr_writer( writable attribute )를 사용했습니다. 그러나를 사용하여 동일한 기능을 달성 할 수 있습니다 attr_accessor. 요컨대, attr_accessor는 getter 및 setter 메소드 모두에 대한 액세스를 제공합니다.

수정 된 코드는 다음과 같습니다.

class Address
    attr_accessor :street  
    def initialize
        @street = ""
    end
end

attr_accessible대량 할당을 허용하려는 모든 열을 나열 할 수 있습니다. 이것의 반대는이 attr_protected필드가 누구에게도 대량 할당이 허용되는 것을 원하지 않음을 의미합니다. 아마 당신이 누군가와 함께 원숭이를 원하지 않는 데이터베이스의 필드가 될 것입니다. 상태 필드 등


2
따라서 마이그레이션에서 필드를 만든 다음 attr_accessible을 사용하여 필드를 사용 가능하게 만들면 getter 및 setter를 만들 필요가 없다고 말하는가? 그러나 필드가 데이터베이스에 없으면 어떻게 attr_accessible이 getter / setter처럼 작동하지 않습니까? "has_secure_password"행을 포함하면 attr_accessible은 데이터베이스에없는 경우에도 getter / setter가 : password 및 : password_confirmation에 충분할 수있게됩니다. 매우 혼란스러운;)


2

빠르고 간결한 차이점 개요 :

attr_accessor클래스에서 읽기 및 쓰기 접근자를 만드는 쉬운 방법입니다. 데이터베이스에 열이 없지만 양식에 필드를 표시하려고 할 때 사용됩니다. 이 필드는 “virtual attribute”Rails 모델입니다.

가상 속성 – 데이터베이스의 열에 해당하지 않는 속성입니다.

attr_accessible 컨트롤러 메소드에서 액세스 할 수있는 속성을 식별하는 데 사용되며 대량 할당에 속성을 사용할 수 있습니다. 지정한 속성에만 액세스 할 수 있으며 나머지는 거부합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.