保存到连接表和常规表

时间:2014-05-07 18:49:28

标签: ruby-on-rails ruby ruby-on-rails-4

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)

1 个答案:

答案 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(注意单数问题

更新

TestQuestion的联接模型名为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