2016-07-20 30 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