간단한 설문 조사/설문지 앱을 만들려고합니다. 설문 조사는 Questions
입니다. 대부분의 질문은 설문지 작성자가 자유 텍스트 응답으로 작성하는 단일 내용 필드 (질문 자체)로 구성됩니다. (이 토론과 관련없는 몇 가지 다른 필드도 있습니다.) 그러나 사용자는 MultipleChoiceQuestions
또는 LikertQuestions
(예 : 1 ~ 5 척도의 답변)을 만들 수도 있습니다. MultipleChoiceQuestions
의 경우 MultipleChoiceQuestion
has_many Answers
과 같은 Answer
이라는 다른 모델이 있습니다. 여기 내 디자인 선택은 내가 아는 지금까지로, 다음과 같습니다예상대로 STI/ActiveRecord 모델을 얻을 수 없습니다.
class Question < ActiveRecord::Base
attr_accessible :id, :content
end
class MultipleChoiceQuestion < Question
attr_accessible :type
end
class LikertQuestion < Question
attr_accessible :type, :min, :max, :label_min, label_max
end
2) 공유 속성과 메소드를 모듈/믹스 인을 사용 :
module Question
@content, @id
def method1
end
end
class MultipleChoiceQuestion < ActiveRecord::Base
include Question
end
class LikertQuestion < ActiveRecord::Base
include Question
attr_accessible :type, :min, :max, :label_min, label_max
end
1) 질문에서 상속 이것은 상속의 명백한 사례 인 것처럼 보이므로 옵션 1로갔습니다. 그 이후로는 작동하지 않습니다. 단일 테이블 상속은 충분히 단순 해 보였으므로 MultipleChoiceQuestion
및 LikertQuestion
을 스키마에 각각 type:string
부여했습니다. 여기에 (dB/schema.rb에서) 각각에 대한 스키마입니다
create_table "questions", :force => true do |t|
t.integer "parent"
t.string "type"
t.string "content"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.integer "survey_id"
end
create_table "multiple_choice_questions", :force => true do |t|
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.string "type"
end
create_table "likert_questions", :force => true do |t|
t.integer "min"
t.integer "max"
t.string "label_min"
t.string "label_max"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.string "type"
end
내가 옵션 1을 구현하는 경우 schema.rb에 명시된 바와 같이, 위, 다음 MultipleChoiceQuestion 및 LikertQuestion 어떻게 든 실제로 고유의 필드 중 하나를 포함하지 않는 ; 대신, 그들은 Question의 상속 된 필드만을가집니다. 콘솔 출력을 참조하십시오에 StackOverflow에
1.9.3p392 :001 > Question
=> Question(id: integer, parent: integer, content: string, created_at: datetime, updated_at: datetime, survey_id: integer)
1.9.3p392 :002 > LikertQuestion
=> LikertQuestion(id: integer, parent: integer, content: string, created_at: datetime, updated_at: datetime, survey_id: integer)
1.9.3p392 :003 > MultipleChoiceQuestion
=> MultipleChoiceQuestion(id: integer, parent: integer, content: string, created_at: datetime, updated_at: datetime, survey_id: integer)
1.9.3p392 :004 > LikertQuestion.new(:min => 3)
ActiveRecord::UnknownAttributeError: unknown attribute: min
누군가가 질문 추상 클래스해야한다고 말했다. 내가 Question.rb에 self.abstract_class = true
를 추가한다면, 나는 다음과 같은 얻을 :
1.9.3p392 :001 > Question
=> Question(abstract)
1.9.3p392 :002 > LikertQuestion
=> LikertQuestion(id: integer, min: integer, max: integer, label_min: string, label_mid: string, label_max: string, created_at: datetime, updated_at: datetime, type: string)
1.9.3p392 :003 > MultipleChoiceQuestion
=> MultipleChoiceQuestion(id: integer, created_at: datetime, updated_at: datetime, type: string)
1.9.3p392 :004 > LikertQuestion.new(:content => "foo")
ActiveRecord::UnknownAttributeError: unknown attribute: content
LikertQuestion
및 MultipleChoiceQuestion
이 만 고유의 필드를 표시하고 부모로부터 필드를 상속하지 않습니다.
1) 여기에 무엇이 누락 되었습니까? 어쨌든 상속이 최적의 솔루션인지 여부에 관계없이 확실한 것을 간과해야합니다.
2) 상속 대신 모듈 접근 방식을 사용해야합니까? 앞서 언급했듯이, 상속은 아무렇지도 않게 느껴졌습니다. LikertQuestion
및 MultipleChoiceQuestion
은 실제로 Questions
의 종류입니다. 모듈 접근법을 사용하면 survey.questions()
, survey.questions.build()
및 아마도 다른 유용한 것들을 말할 수있는 능력을 잃게됩니다. 이 상황에서 Rails hotshots는 무엇을합니까? 그게 뭐든 할거야.
StackOverflow에 대한 글은 아니지만, 서브 클래 싱과 mixin의 장단점에 대한 매우 포괄적 인 토론을 제공합니다.
Ruby 1.9.3 (2.0으로 전환 할 생각 임), Rails 3.2.3.
레일 1.9.3 또는 루비 1.9.3? – sosborn
@sosborn : "Rails 1.9.3"은 오타 일 뿐이며 * Ruby * 1.9.3을 사용하고 있다는 것이 꽤 분명하다고 생각합니다. –
@mu, 실수라고 알고 있지만 오타라고 생각하지 않습니다. – sosborn