has_many 通过访问加入表单中的 table 属性
has_many through access join table attribute 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
想法是通过某些配置来创建随机考试,因此这 table 有助于 select 您需要哪些部分,然后 select 每个部分的问题数量部分,这里是每个 table:
的属性
随机考试:姓名(字符串),created_at(日期时间),updated_at(日期时间)
部分:名称(字符串),created_at(日期时间),updated_at(日期时间)
随机考试部分:random_exam_id(整数),section_id(整数),questions_number(整数)
如您所见,每个部分的问题数属性在 RandomExamSections table 中,我想以从 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
结束
我在 assign_random_questions_number
方法中更新记录时遇到类型错误:TypeError: nil is not a symbol nor a string
当我在控制台运行这个
时甚至会出现这个错误
random = RandomExamSection.first
random.update(questions_number: 10)
或者当我 运行:
random = RandomExamSection.first
random.questions_number = 10
random.save
编辑
我最终删除了 RandomExamSection 中的关联并在 'assign_random_questions_number' 中用 questions_number
重新创建了它
谢谢。
如果你使用 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.
这里的技巧是在控制器上构建,然后在视图上 select 并在模型上验证 selected。如果您需要帮助,我在这里举了一个例子:https://github.com/afromankenobi/nested_attr_demo
要在 random_exam_sections 已创建时添加部分,您可能应该使用 javascript。也许这个 railscasts 可以帮助你 http://railscasts.com/episodes/196-nested-model-form-part-1
我有以下型号:
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
想法是通过某些配置来创建随机考试,因此这 table 有助于 select 您需要哪些部分,然后 select 每个部分的问题数量部分,这里是每个 table:
的属性随机考试:姓名(字符串),created_at(日期时间),updated_at(日期时间)
部分:名称(字符串),created_at(日期时间),updated_at(日期时间)
随机考试部分:random_exam_id(整数),section_id(整数),questions_number(整数)
如您所见,每个部分的问题数属性在 RandomExamSections table 中,我想以从 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
结束
我在 assign_random_questions_number
TypeError: nil is not a symbol nor a string
当我在控制台运行这个
时甚至会出现这个错误random = RandomExamSection.first
random.update(questions_number: 10)
或者当我 运行:
random = RandomExamSection.first
random.questions_number = 10
random.save
编辑
我最终删除了 RandomExamSection 中的关联并在 'assign_random_questions_number' 中用 questions_number
重新创建了它谢谢。
如果你使用 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.
这里的技巧是在控制器上构建,然后在视图上 select 并在模型上验证 selected。如果您需要帮助,我在这里举了一个例子:https://github.com/afromankenobi/nested_attr_demo
要在 random_exam_sections 已创建时添加部分,您可能应该使用 javascript。也许这个 railscasts 可以帮助你 http://railscasts.com/episodes/196-nested-model-form-part-1