2016-07-20 11 views
1

Ich habe folgende Modelle:has_many durch den Zugang Join-Tabelle Attribut in Form

class RandomExam < ActiveRecord::Base 
    has_many :random_exam_sections 
    has_many :sections, :through => :random_exam_sections 
end 

class Section < ActiveRecord::Base 
    has_many :random_exam_sections 
    has_many :random_exams, :through => :random_exam_sections 

class RandomExamSection < ActiveRecord::Base 
    belongs_to :random_exam 
    belongs_to :section 
end 

Die Idee ist, bestimmte Konfigurationen haben zufällige Prüfungen zu erstellen, so dass diese Tabellen helfen, um auszuwählen, welche Abschnitte Sie brauchen und dann auch wählen Sie die Anzahl der Fragen pro Abschnitt, hier sind die Attribute jeder Tabelle:

RandomExam: (String), created_at (Datumzeit), updated_at (Datumzeit)

Sektion: (String), created_at (Datumzeit), aktualisiert_at (datetime)

RandomExamSection: random_exam_id (integer), SECTION_ID (integer), questions_number (integer)

Wie Sie die Anzahl der Fragen pro Abschnitt Attribut sehen können, ist in dem RandomExamSections Tisch und ich möchte es in einem Formular zuzugreifen, angezeigt wird, hier von der RandomExam Controller ist meine Form:

<%= form_for (@random_exam) do |f| %> 
    <div class="row"> 

     <div class="input-field col s12"> 
      <%= f.label :name, 'Name' %> 
      <%= f.text_field :name, placeholder: 'Enter the name of the  configuration' %> 
     </div> 

    </div> 

    <% @sections.each do |section| %> 

     <div class="row <%= dom_id(section) %>"> 
      <div class="col s4"> 
       <%= check_box_tag 'random_exam[section_ids][]', section.id, 
       @random_exam.section_ids.include?(section.id), id:  dom_id(section), class: "section-checkbox #{dom_id(section)}" %> 
       <%= label_tag dom_id(section), (raw sanitize  section.name, tags: %w(h2 p strong em a br b i small u ul ol li  blockquote), attributes: %w(id class href)), 
       class: "name #{dom_id(section)}" %> 
      </div class="col s4"> 
      <div> 
       <%= text_field_tag "random_exam[random_questions_numbers][#{section.id}][]", nil, 
            :placeholder => 'Enter the number of questions' %> 
      </div> 

     </div> 
    <% end %> 

    <div class="form-group"> 
     <%= f.submit class: "btn waves-effect waves-light green" %> 
    </div> 

<% end %> 

Mein Controller:

def create 
    @random_exam = RandomExam.new(random_exam_params) 
    if @random_exam.save 
    assign_random_questions_number 
    flash[:success] = 'Random configuration created successfully' 
    redirect_to @random_exam 
else 
    flash.now[:danger] = @random_exam.errors.full_messages.to_sentence 
    render 'new' 
end 

def assign_random_questions_number 
    if params[:random_exam][:'random_questions_numbers'] == nil 
    return 
    end 


params[:random_exam][:'section_ids'].each do |key, value| 
    record = RandomExamSection.search_ids(@random_exam.id, key) 

    record.each do |random_exam_section_record| 
    number_of_questions = params[:random_exam][:'random_questions_numbers'][key].first.to_i 
    random_exam_section_record.update(questions_number: number_of_questions) 
    end 
end 

Ende

Ich erhalte eine Typeerror: TypeError: nil is not a symbol nor a string, wenn ich den Rekord in der

Dieser Fehler assign_random_questions_number Methode aktualisieren erscheint, auch wenn ich dies auf der

Konsole laufen
random = RandomExamSection.first 
random.update(questions_number: 10) 

Oder wenn ich laufe:

BEARBEITEN

Ich löschte die Zuordnung i n RandomExamSection und neu erstellen es innerhalb 'assign_random_questions_number' mit der Frage Nummer

Vielen Dank.

+0

Hallo und willkommen zu stapeln Überlauf. Also - ich bemerke, dass es für diese Anzahl von Abschnitten überhaupt kein Formularfeld gibt. Was hast du versucht, in deine Form zu bringen, um diese Arbeit zu machen und was, wenn überhaupt, Fehler hast du gesehen, als du das versucht hast? –

+0

@TarynEast Nun, ich habe mehrere Stack-Overflow-Antworten versucht, das Problem ist, dass sie verschachtelte Felder verwenden, nicht etwas, das wir in unserer Implementierung verwenden. In der Tat haben wir keine Ahnung, wie das Feld benannt werden sollte, denn wenn wir es speichern, erscheint es nicht. – Dazt

+0

so ...Zeige uns, was du probiert hast (bearbeite deine Frage und lege sie dort hin), und wir können dir helfen, es zu beheben, damit es erscheint :) AFAICT es ist nur ein anderes Feld ... also füge ein weiteres Feld mit dem Namen was du willst. –

Antwort

1

Wenn Sie nested_attributes verwenden, können Sie etwas tun:

#form 
<h4>Selected exams</h4> 
<%= f.fields_for :random_exam_sections do |b| %> 
    <%= b.hidden_field :section_id %> 
    <%= b.label :selected, b.object.section.name %> 
    <%= b.check_box :selected, { checked: !b.object.id.blank? } %> 
    <br> 
    <%= b.label :question_numbers %> 
    <%= b.text_field :questions_number %> 
<% end %> 

#RandomExamModel 
class RandomExam < ApplicationRecord 
    has_many :random_exam_sections, inverse_of: :random_exam 
    has_many :sections, :through => :random_exam_sections 

    accepts_nested_attributes_for :random_exam_sections, reject_if: :is_not_selected 


    private 
    def is_not_selected(attr) 
    attr["selected"] == '0' 
    end 
end 

# RandomExam 
class RandomExamSection < ApplicationRecord 
    belongs_to :random_exam 
    belongs_to :section 

    attr_accessor :selected 
end 

# Controller 
# GET /random_exams/new 
    def new 
    @random_exam = RandomExam.new 
    @random_exam.random_exam_sections.build(Section.all.map{|s| {section_id: s.id}}) 
    end 

Die Idee grundsätzlich

ist
- Build on controller the random_exam_sections to be selected 
- Write a form that allows to you 'select' one option and assign the number 
- Then, validate if the random_exam_section of a sections was selected (this why i made that `attr_accessor :selected`, i need a place to write if user select the exam_section) 
- If was selected, save. 

Der Trick hier ist auf dem Controller bauen, wählen Sie dann auf der Anzeige und Validierung der ausgewählt auf dem Modell. Hier habe ich ein Beispiel gemacht, wenn Sie Hilfe benötigen: https://github.com/afromankenobi/nested_attr_demo

Um Abschnitte hinzuzufügen, wenn random_exam_sections bereits erstellt wird, sollten Sie wahrscheinlich Javascript verwenden. Vielleicht kann diese Railscasts Ihnen helfen http://railscasts.com/episodes/196-nested-model-form-part-1

+0

Diese Lösung ist großartig, Das einzige Problem ist, dass ich alle Kontrollkästchen jedes Mal zeigen muss, auch wenn der Benutzer die Datensätze bearbeitet – Dazt

+0

Hallo! Sie können einen selektiven Build auf create erstellen, um nur die Datensätze für die Abschnitte zu erstellen, die nicht ausgewählt sind. Schauen Sie [this] (https://github.com/afromarkenobi/nested_attr_demo/blob/master/app/controllers/random_exams_controller.rb#L22) Methode https://github.com/afromarkenobi/nested_attr_demo/blob/master/app/ Controller/random_exams_controller.rb # L22 –

+0

Ich habe eine andere Arbeit verwendet, aber Ihre Antwort war sehr gut, danke. Ich werde es als die richtige Antwort markieren. Es wäre großartig, wenn Sie die Frage abstimmen könnten, ich denke, dass viele Leute damit kämpfen. Vielen Dank für Ihre Zeit. – Dazt