2016-07-20 55 views
1

我有以下型號:的has_many通過訪問加盟形式表屬性

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 

的想法是有一定的配置,以創建隨機考試,所以這個表有助於選擇你需要哪些板塊,然後還選擇的每部分問題的數量,這裏有每個表的屬性:

RandomExam:名稱(字符串),created_at(日期時間)的updated_at(日期時間)

科:名稱(字符串),created_at(日期時間),updated_at(日期時間)

RandomExamSection:random_exam_id(整數),SECTION_ID(整數),questions_number(整數)

正如你所看到的每節屬性的問題數是RandomExamSections表裏面,我想訪問的形式從RandomExam控制器顯示,這裏是我的表格:

<%= 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 %> 

我的控制器:

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 

我得到一個類型錯誤:TypeError: nil is not a symbol nor a string當我在方法更新記錄assign_random_questions_number

此錯誤,甚至當我在控制檯上運行,這似乎

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

或者當我運行:

random = RandomExamSection.first 
random.questions_number = 10 
random.save 

編輯

我結束了刪除關聯我n RandomExamSection並在'assign_random_questions_number'內使用question_number重新創建它

謝謝。

+0

嗨,歡迎來到堆棧溢出。所以 - 我注意到根本沒有任何形式的字段。你試圖在你的表格中加入什麼來完成這項工作,以及在你嘗試這些時發現了什麼(如果有的話)錯誤? –

+0

@TarynEast那麼,我已經嘗試了幾個堆棧溢出的答案,問題是他們使用嵌套字段,而不是我們在實現中使用的東西。事實上,我們不知道該字段應該命名,因爲當我們保存它時,它不會出現。 – Dazt

+0

so ...告訴我們你試過了什麼(編輯你的問題並把它放在那裏),我們可以幫助你修復它,使它確實出現:) AFAICT它只是另一個領域...所以添加另一個名爲你想要的領域。 –

回答

1

如果使用nested_attributes你可以做這樣的事情:

#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 

的想法基本上是

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

這裏的技巧是建立在控制器上,然後選擇視圖和驗證在模型上選擇。在這裏,我舉了一個例子,如果你需要幫助:https://github.com/afromankenobi/nested_attr_demo

要添加部分時,random_exam_sections已被創建,你應該使用JavaScript。也許這個railscasts可以幫助你http://railscasts.com/episodes/196-nested-model-form-part-1

+0

此解決方案非常棒,唯一的問題是我需要每次顯示所有的複選框,即使用戶正在編輯記錄 – Dazt

+0

嗨!你可以在創建時做一個選擇性的構建來構建沒有被選擇的部分的記錄。看[這](https://github.com/afromankenobi/nested_attr_demo/blob/master/app/controllers/random_exams_controller.rb#L22)方法https://github.com/afromankenobi/nested_attr_demo/blob/master/app/控制器/ random_exams_controller.rb#L22 –

+0

我用另一種工作,但你的答案是非常好的,謝謝。我會將其標記爲正確的答案。如果你能夠投票回答這個問題會很棒,我想很多人都在爲此而苦苦掙扎。感謝您的時間。 – Dazt