nested_form没有保存到模型Rails 3

时间:2013-04-13 12:21:32

标签: ruby-on-rails ruby-on-rails-3 forms nested-forms model-associations

我认为我正处于以下的正确道路上,尽管我无法将表单数据保存到模型中。我有2个型号

class Prediction < ActiveRecord::Base
  attr_accessible :home_team, :away_team, :home_score, :away_score, :fixtures_attributes

  has_many :fixtures
  accepts_nested_attributes_for :fixtures
end

class Fixture < ActiveRecord::Base
  attr_accessible :home_team, :away_team, :fixture_date, :kickoff_time

  belongs_to :predictions
end

为了创建一个新的预测记录,我有一个表单可以获取所有的灯具并预填充表单,用户只需在每个团队旁边添加分数

<%= form_for @prediction do |f| %>
<!-- Gets all fixtures -->
<%= f.fields_for :fixtures, @fixtures<!-- grabs as a collection --> do |ff| %>

<%= ff.text_field :home_team %> VS <%= ff.text_field :away_team %><%= f.text_field :home_score %><%= f.text_field :away_score %><br>

<% end %>
<%= f.submit 'Submit Predictions' %>
<% end %>

然后我让我的控制器来处理新的/创建动作,我认为这可能是我摔倒的地方

class PredictionsController < ApplicationController

def new
 @prediction = Prediction.new
 @prediction.fixtures.build
 @fixtures = Fixture.all
end

 def create
  @prediction = Prediction.new(params[:prediction])
  @prediction.save
   if @prediction.save
    redirect_to root_path, :notice => 'Predictions Submitted Successfully'
   else
    render 'new'
end
  end
 end

最后是我的路线

resources :predictions
resources :fixtures

因此,当我提交表单时,我收到错误

ActiveRecord::RecordNotFound in PredictionsController#create
Couldn't find Fixture with ID=84 for Prediction with ID=

查看正在解析的params(下面的快照),看起来不对,因为home_score和away_score没有通过。

{"utf8"=>"✓",
 "authenticity_token"=>"DfeEWlTde7deg48/2gji7zSHJ19MOGcMTxEsQEKdVsQ=",
  "prediction"=>{"fixtures_attributes"=>{"0"=>{"home_team"=>"Arsenal",
 "away_team"=>"Norwich",
 "id"=>"84"},
 "1"=>{"home_team"=>"Aston Villa",
 "away_team"=>"Fulham",
 "id"=>"85"},
 "2"=>{"home_team"=>"Everton",
 "away_team"=>"QPR",
 "id"=>"86"}

表单的当前输出

image

任何建议表示赞赏

由于

2 个答案:

答案 0 :(得分:1)

当您在预测控制器中的新方法中将@fixtures设置为Fixture.all时,您将包括每个灯具,而不仅仅是属于您的预测的灯具。当表单的结果传递给创建控制器时,会有与其他预测相关联的固定装置,这是您报告的错误的来源。也许你想要@fixtures = @prediction.fixtures

之类的东西

你在fields_for区块中所做的事情在我的眼中看起来也是错误的。您对f.text_fieldhome_score输入使用了away_score。这将在每个夹具区域中为预测模型重复相同的形式元素。你不会从中得到你想要的结果。说实话,我很难理解这种关联是如何理解的。你能解释一下好一点吗?我怀疑你的模型并不像你需要的那样完整。

编辑:

好吧,我想我现在对你想要达到的目标有了更好的了解。您试图在一个表单中创建许多预测,并从现有灯具列表中预填充home_team和away_team,对吗?

好吧,假设是这样,你肯定是以错误的方式接近它。您不需要预测和夹具模型之间的多对一关系(正如您所推测的那样)。您需要做的是通过迭代灯具集合并填充当前灯具实例中的home_teamaway_team字段来生成表单。你真的需要这些是可编辑的文本字段,还是只是将它们放在文本字段中以便它们通过?如果是这样,您可以使用隐藏字段。

现在的问题是,Rails不容易在一个表单中创建多个记录。这不是我以前做过的事情,它会让我有点试错,但这里有一种最好的猜测方法。

models

class Prediction < ActiveRecord::Base
  attr_accessible :home_team, :away_team, :home_score, :away_score, :fixtures_attributes
end

class Fixture < ActiveRecord::Base
  attr_accessible :home_team, :away_team, :fixture_date, :kickoff_time
end

controller

class PredictionsController < ApplicationController

  def new
    @prediction = Prediction.new
    @fixtures = Fixture.all
  end

  def create
    begin
      params[:predictions].each do |prediction|
        Prediction.new(prediction).save!
      end
      redirect_to root_path, :notice => 'Predictions Submitted Successfully'
    rescue
      render 'new'
    end
  end

end

view

<%= form_tag controller: 'predictions', action: 'create', method: 'post' do %>
  <% @fixtures.each do |fixture| %>
    <%= fixture.home_team %> vs <%= fixture.away_team %>
    <%= hidden_field_tag "predictions[][home_team]", fixture.home_team %>
    <%= hidden_field_tag "predictions[][away_team]", fixture.away_team %>
    <%= text_field_tag "predictions[][home_score]" %>
    <%= text_field_tag "predictions[][away_score]" %><br />
  <% end %>
  <%= submit_tag "Submit predictions" %>
<% end %>

所以基本上我正在创建一个返回参数数组的表单。在这种情况下,我无法使用模型表单助手。

解决这个问题的一种方法是创建一个具有多个预测的虚拟模型,并使用它创建一个嵌套的表单。

无论如何,这是许多未经测试的代码,可能永远不会被看到,所以我暂时将它留在那里。

答案 1 :(得分:0)

我没有花很多时间看,因为我的妻子很快就让我离开了。但是如果我理解了你的视图中的每一行都是来自灯具和预测模型关联。你得到的params哈希是一团糟,因为默认行为将是一个更新单个记录ID的视图。因此,您将多个记录放入单个视图中,并尝试一次更新多个记录。

模型中的创建方法

@prediction = Prediction.new(params[:prediction])

但你传递的params哈希是这样的:

{"utf8"=>"✓",
 "authenticity_token"=>"DfeEWlTde7deg48/2gji7zSHJ19MOGcMTxEsQEKdVsQ=",
  "prediction"=>{"fixtures_attributes"=>{"0"=>{"home_team"=>"Arsenal",
 "away_team"=>"Norwich",
 "id"=>"84"},
 "1"=>{"home_team"=>"Aston Villa",
 "away_team"=>"Fulham",
 "id"=>"85"},
 "2"=>{"home_team"=>"Everton",
 "away_team"=>"QPR",
 "id"=>"86"}

因此,您必须在预测控制器中的create方法中获得更多逻辑,以迭代您正在接收的哈希并一次保存每一行。