Ruby on Rails 4
希望表单创建引用问题的测试记录。因此,测试有很多问题,而问题有很多测试。当表单提交时,它正在创建测试记录,但是说问题参数是不允许的。但是问题param也不应该保存到Test中,它应该保存到我的questions_tests
表中。你怎么做到这一点?这样我就可以用表格选择的问题来展示测试。
型号:
class Test < ActiveRecord::Base
has_many :questions_tests
has_many :questions, :through => :questions_tests
accepts_nested_attributes_for :questions
end
class Question < ActiveRecord::Base
has_many :answers, dependent: :destroy
has_many :test_questions
has_many :tests, :through => :questions_tests
end
class QuestionTest < ActiveRecord::Base
belongs_to :test
belongs_to :question
end
控制器:
#tests_controller.rb
def create
respond_to do |format|
if test = Test.create(test_params)
@test = []
@test << test
question_test = @test.find(test.id)
format.html { redirect_to @test, notice: 'Test was successfully created.' }
format.json { render action: 'show', status: :created, location: @test }
else
format.html { render action: 'new' }
format.json { render json: @test.errors, status: :unprocessable_entity }
end
end
end
def test_params
params.require(:test).permit(:name, :user_id, :type, :category, :description, :question, question_attributes: [ :id, :content, :category ] ).
merge user_id: current_user.id
end
形式:
<%= form_for(@test) do |f| %>
<div class="field">
<%= f.label :name %><br>
<%= f.text_field :name %>
</div>
<div class="field">
<%= f.label :type %><br>
<%= f.text_field :type %>
</div>
<div class="field">
<%= f.label :category %><br>
<%= f.select :category, [ ["one", "one"], ["two", "two"] ], {prompt: "Select Category"}, class: "input-lg" %>
</div>
<div class="field">
<%= f.label :description %><br>
<%= f.text_field :description %>
</div>
<div class="field">
<%= f.label :question %><br>
<%= f.fields_for :question do |question| %>
<%= question.collection_select :question_id, Question.where({ category: "ip_voice" }), :id, :content, {prompt: "Select Question"}, {class: "form-control input-lg"} %>
<% end %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
日志:
Started POST "/tests" for x at 2014-05-07 14:34:59 -0400
Processing by TestsController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"x=", "test"=>{"name"=>"thoo", "type"=>"", "category"=>"one", "description"=>"chickens on the road", "question"=>{"question_id"=>"1"}}, "commit"=>"Create Test"}
Unpermitted parameters: question
User Load (0.3ms) SELECT "users".* FROM "users" WHERE "users"."remember_token" = 'ca9a73ab72a94f538723de34856a92dcde068e7b' LIMIT 1
(0.0ms) begin transaction
SQL (0.3ms) INSERT INTO "tests" ("category", "created_at", "description", "name", "type", "updated_at", "user_id") VALUES (?, ?, ?, ?, ?, ?, ?) [["category", "ip_voice"], ["created_at", Wed, 07 May 2014 18:34:59 UTC +00:00], ["description", "chickens on the road"], ["name", "thoo"], ["type", ""], ["updated_at", Wed, 07 May 2014 18:34:59 UTC +00:00], ["user_id", 1]]
(17.1ms) commit transaction
Redirected to http://0.0.0.0:3000/tests/11
Completed 302 Found in 40ms (ActiveRecord: 17.7ms)
答案 0 :(得分:3)
Test
has_many questions
。
您需要更新test_params
方法以反映:
def test_params
params.require(:test).permit(:name, :user_id, :type, :category, :description, questions_attributes: [ :id, :content, :category ] ).
merge user_id: current_user.id
end
除非:question
表中有一个名为question
的属性,否则此处不需要tests
。此外,您应该使用questions_attributes
(注意复数问题)而不是question_attributes
(注意单数问题)
在同一行,您需要更新视图中的fields_for
,如下所示:
<%= f.fields_for :questions do |question| %>
:questions
(注意复数问题)而非:question
(注意单数问题)
更新
Test
和Question
的联接模型名为QuestionTest
,因此您应该在关联中将其称为question_tests
(对于has_many
)
您错误地设置了关联,请按以下方式更新它们:
class Test < ActiveRecord::Base
has_many :question_tests ## "question_tests" and NOT "questions_tests"
has_many :questions, :through => :question_tests ## "question_tests" and NOT "questions_tests"
accepts_nested_attributes_for :questions
end
class Question < ActiveRecord::Base
has_many :answers, dependent: :destroy
has_many :question_tests ## "question_tests" and NOT "test_questions"
has_many :tests, :through => :question_tests ## "question_tests" and NOT "questions_tests"
end
已实施解决方案希望这可以帮助任何需要类似结果的人。
tests_controller.rb
def new
@test = Test.new
end
def create
@test = Test.new(test_params)
@test.save
end
_form.html.erb
<%= form_for(@test) do |f| %>
...
<div class="field">
<%= f.label :question %><br>
<%= f.collection_check_boxes :question_ids, Question.all.to_a.collect, :id, :content %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
联接表的架构,确保您没有id:false
:
create_table "question_tests", force: true do |t|
t.integer "test_id", null: false
t.integer "question_id", null: false
end