【发布时间】:2021-09-20 19:02:53
【问题描述】:
我正在 Rails (5.2.6) 中构建一个表单,我想使用 accepts_nested_attributes_for,就像在 this question 中一样。但是,该问题的答案不起作用,我怀疑这是因为我的模型已经 belongs_to 另一个模型。
背景 本质上,我正在存储 AB 测试的结果。我想要实现的是让客户拥有他们跟踪测试的独特指标的能力。 Metrics 模型允许用户识别要跟踪的额外方面,而 Outcomes 旨在存储该数据。
我的尝试
我想在记录结果的同时记录结果;我的方法是在测试模型上添加accepts_nested_attributes_for :outcomes,但我不断收到Unpermitted parameter: :outcome 错误。
这是我的模型:
class Client < ApplicationRecord
has_many :tests, dependent: :destroy
has_many :metrics, dependent: :destroy
validates :name, presence: true
end
class Metric < ApplicationRecord
belongs_to :client
has_many :outcomes, dependent: :destroy
has_many :tests, through: :outcomes
validates :name, presence: true
validates :data_type, presence: true
end
class Test < ApplicationRecord
belongs_to :client
has_many :results
has_many :outcomes
has_many :metrics, through: :outcomes
accepts_nested_attributes_for :outcomes, allow_destroy: true
validates :name, presence: true
end
class Result < ApplicationRecord
belongs_to :test
end
class Outcome < ApplicationRecord
belongs_to :metric
belongs_to :test
validates :result, presence: true
end
和(一些)我的控制器:
class TestsController < ApplicationController
def show
@client = Client.find(params[:client_id])
@test = @client.tests.find(params[:id])
end
def new
@client = Client.find(params[:client_id])
@test = @client.tests.new
@test.build_outcome
end
def create
@client = Client.find(params[:client_id])
@test = @client.tests.create(test_params)
redirect_to client_path(@client)
end
def edit
@client = Client.find(params[:client_id])
@test = @client.tests.find(params[:id])
end
def update
@client = Client.find(params[:client_id])
@test = @client.tests.find(params[:id])
if @test.update(test_params)
redirect_to client_test_path(@client, @test)
else
render 'edit'
end
end
def destroy
@client = Client.find(params[:client_id])
@test = @client.tests.find(params[:id])
@test.destroy
redirect_to client_path(@client)
end
private
def test_params
params.require(:test).permit(:name, outcome_attributes: [:result])
end
end
class OutcomesController < ApplicationController
def show
@test = Test.find(params[:test_id])
@outcome = @test.outcome.find(params[:id])
end
def create
@test = Test.find(params[:test_id])
@outcome = @test.outcomes.create(outcome_params)
redirect_to test_path(@test)
end
def edit
@test = Test.find(params[:test_id])
@outcome = @test.outcomes.find(params[:id])
end
def update
@test = Test.find(params[:test_id])
@outcome = @test.outcomes.find(params[:id])
if @outcome.update(outcome_params)
redirect_to test_outcome_path(@test, @outcome)
else
render 'edit'
end
end
def destroy
@test = test.find(params[:test_id])
@outcome = @test.outcomes.find(params[:id])
@outcome.destroy
redirect_to test_path(@test)
end
private
def outcome_params
params.require(:outcome).permit(:test)
end
end
还有形式:
<%= form_with model: [ @test, @test.results.build ] do |form| %>
<p>
<%= form.label :participants %><br>
<%= form.number_field :participants %>
</p>
<p>
<%= form.label :completed %><br>
<%= form.number_field :completed %>
</p>
<p>
<%= form.label :confidence %><br>
<%= form.number_field :confidence %>
</p>
<% if @test.client.metrics.count > 0 %>
<%= form.fields_for :outcome do |a| %>
<% @test.client.metrics.each do |m| %>
<p>
<%= a.label m.name %><br>
<%= a.number_field :result %>
</p>
<% end %>
<% end %>
<% end %>
<p>
<%= form.submit %>
</p>
<% end %>
【问题讨论】:
标签: ruby-on-rails ruby-on-rails-5