Rails — STI없이 유형 열을 사용 하시겠습니까?


81

나는라는 열을 사용하려면 type단일 테이블 상속을 호출하지 않고 (STI) - 나는 단지 원하는 type보유하고 정상적인 열 수 String.

Rails가 단일 테이블 상속을 기대하고 예외를 던지지 않고 어떻게 할 수 The single-table inheritance mechanism failed to locate the subclass...This error is raised because the column 'type' is reserved for storing the class in case of inheritance.있습니까?

이를 수행하는 방법에 대한 아이디어가 있습니까?

답변:


134

Rails 3.1 set_inheritance_column은 더 이상 사용되지 않으며 nil다음과 같이 이름으로 사용할 수도 있습니다 .

class Pancakes < ActiveRecord::Base
    self.inheritance_column = nil
    #...
end

실제로 rails 3.2. apidock 에 따르면 : '이 방법은 더 이상 사용되지 않거나 최신 안정 버전으로 이동되었습니다. 마지막 기존 버전 (v3.1.0)이 여기에 표시됩니다. ' 팁 주셔서 감사합니다!
Batkins 2010 년

그것은 3.1에서 사용되지 않는 3.2에서 제거하고, 생각
발렌틴 Nemcev

2
@Batkins inheritance_column독자가 이동되었습니다 (따라서 "사용되지 않거나 이동 됨"알림). inheritance_column인스턴스 변수를 직접 설정하는 사용 은 의도 된 것이며 더 이상 사용되지 않습니다.
lulalala

레일 5.1에서 근무
존 Bachir

21

다음을 사용하여 STI 열 이름을 재정의 할 수 있습니다 set_inheritance_column.

class Pancakes < ActiveRecord::Base
    set_inheritance_column 'something_you_will_not_use'
    #...
end

따라서 아무것도 사용하지 않을 열 이름을 선택하고 set_inheritance_column.


2
실제로 데이터베이스에 해당 열을 만들어야합니까?
Kvass

감사합니다. 프레임 워크는 절대 !!!!! 이제까지!!!! 테이블 필드의 이름을 지정할 수 없습니다. 레거시 데이터 세트에는 좋지 않습니다.
Jon

5
@Jon : Rails는 레거시 데이터 나 다른 사람들과 잘 어울리는 것에 신경 쓰지 않습니다. Rails는 그것에 대해 너무 많은 태도를 가지고 있습니다. 약간의 노력으로 스스로 작동하도록 만들 수 있지만 Rails가 계획하지 않은 작업을 수행해야하는 경우 (불행히도 많은 기본 데이터베이스 개념을 포함) 항상 약간의 싸움을하게됩니다. 다른 레일 사람들이 확실히 이데올로기 문제를 :) 지적 나와 함께 화가 될 수 있도록 OTOH, 나는 전문적인 이단이야
MU가 너무 짧은

10
Rails / Ruby는 구성보다 관습을 선호하기 때문에 옳다고 생각하는 사용 사례에 맞게 최적화하려고합니다.
Ibrahim

21

나는이 질문이 다소 오래되었고 이것은 당신이 묻는 질문과 약간 다르다는 것을 알고 있지만, 열 유형 또는 something_type의 이름을 지정하려는 충동을 느낄 때마다 항상하는 것은 유형의 동의어를 검색하고 대신 사용하는 것입니다.

다음은 몇 가지 대안입니다 : 종류, 정렬, 다양성, 카테고리, 세트, ​​장르, 종, 순서 등.


10

Rails 4.x

Rails 4앱 에서 문제가 발생 했지만 Rails 4 에서는 set_inheritance_column메서드가 전혀 존재하지 않으므로 사용할 수 없습니다.

나를 위해 일한 해결책은 다음과 같이 ActiveRecordinheritance_column메서드 를 재정 의하여 단일 테이블 상속을 비활성화하는 것입니다.

class MyModel < ActiveRecord::Base

  private

  def self.inheritance_column
    nil
  end

end

도움이 되었기를 바랍니다.


8
더 간단한 버전 : class MyModel < ActiveRecord::Base self.inheritance_column = nil end. 참조 : apidock.com/rails/ActiveRecord/ModelSchema/ClassMethods/…
Benj

1
레일 4.2.2에서 나를 위해 작동합니다. 변경 후 서버 또는 스프링을 다시 시작하지 않았습니까?
Benj

1
그리고 다른 사용자는 내가 언급 한 더 간단한 버전이 유용하다고 생각할 수 있습니다. 다시로드 문제에 관해서는 전문가는 아니지만 클래스 정의를 언로드하고 다시로드하지 않고는 클래스 속성이 자동으로 다시로드되지 않는 것이 합리적입니다.
Benj

2
나는 당신의 반응을 이해하지 못합니다. 나는 당신의 대답에 유용한 추가를 제공하려고 노력하고 있습니다. 왜 기분이 상했습니까? 나는 평화를 온
Benj

2
@Benj 그들이 당신이 언급하는 모든 댓글을 삭제 한 것 같아서 이제는 당신이 자신과 논쟁하는 것처럼 보입니다. ;)
Joshua Pinter

0

모든 모델에 대해이 작업을 수행하려면 이니셜 라이저에이를 고정 할 수 있습니다.

ActiveSupport.on_load(:active_record) do
  class ::ActiveRecord::Base
    # disable STI to allow columns named "type"
    self.inheritance_column = :_type_disabled
  end
end

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