Вопрос

Referring to this post: Rails: Deal with several similar model classes?

Using combination of STI and Store feature to organize very similar models.

"Declare a base model for Student with a text column called settings.

class Student < ActiveRecord::Base
  store :settings
  # name, email, phone, address etc..
end

class HighSchoolStudent < Student
  # declare HighSchoolStudent specific attributes 
  store_accessor :settings, :gpa
end

How can I create a form for a HighSchoolStudent, while remaining under the Student controller?

I dont want to add a separate controller or route resource for HighSchoolStudent, is there a way to have one form for Student and HighSchoolStudent, with a checkbox to indicate whether its a Student or a HighSchoolStudent? Can I only require that the extra attributes created for the subclass are only required for the form to be submitted if that specific class is checked?

<%= simple_form_for(@student, html: {class: "form-horizontal"}) do |f| %>
<%= f.input :name, as: :text, input_html: {rows: "1"} %>
<%= f.input :email, as: :text, input_html: {rows: "2"} %>

<%= f.input :gpa, as: :text, input_html: {rows: "1"} %>


<%= f.button :submit, class: "btn btn-primary" %>
Это было полезно?

Решение

Sure, you can make an arbitrary checkbox, and check its value in the create action:

# In your view
<%= check_box_tag :high_school %>

# In your controller
def create
  base_class = params[:high_school] ? HighSchoolStudent : Student
  base_class.create(params[:student])
  ...
end

Any validations specific to HighSchoolStudent will be ensured only if the checkbox was checked.

Другие советы

Rails STI uses the type special column to store the class name. Student.new(type: 'HighSchoolStudent') would build a Student which would later act as a HighSchoolStudent.

This solution would not run validations, callbacks, etc. defined only for HighSchoolStudent but would run everything from Student.

To do that, you could do something like @PinnyM suggested, or you could have a hidden input for the type attribute: hidden_field_tag :type, 'Student' followed by a check_box_tag :type, 'HighSchoolStudent' and use that to determine the right class to create, which does buy you all of the validations and callbacks while being more maintainable as it uses the correct attribute.


All that to say, STI may be the wrong solution for you here.

Can I only require that the extra attributes created for the subclass are only required for the form to be submitted if that specific class is checked?

This tells me that you've added - to your students table - attributes which are irrelevant to non-HighSchool students.

A better solution might be to have a class like HighSchoolStudentProfile as an association and a method high_schooler? on student that checks for its presence. This prevents you from running into a problem I've faced before, which is having a "sparse table" and which generally grows into needing various conditional validations and has complex logic.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top