2017-03-09 109 views
1

我有表任务和项目。我有一个表单,记录了我的任务可能有的所有可能的项目,工作正常。然后我有任务的形式,其中所有项目都显示在一个字段旁边,以便为每个项目设置成本值。这将导致Task和Item之间的连接:TaskItem(该表包含task_id,item_id和成本)。Rails没有保存嵌套属性

当我提交表单,它的节能任务,但相关不TaskItems。我没有看到我错过了什么,因为我搜索了很多这个问题,似乎没有任何工作。请参阅下面的代码。      

型号:

class Task < ApplicationRecord 
    has_many :task_items 
    has_many :items, :through => :task_items 

    accepts_nested_attributes_for :task_items, :allow_destroy => true 
end 

class Item < ApplicationRecord 
    has_many :task_items 
    has_many :tasks, :through => :task_items 
end 

class TaskItem < ApplicationRecord 
    belongs_to :task 
    belongs_to :item 

    accepts_nested_attributes_for :item, :allow_destroy => true 
end 

控制器:

def new 
    @items = Item.all 

    @task = Task.new 
    @task.task_items.build 
end 

def create 
    @task = Task.new(task_params) 
    @task.save 
    redirect_to action: "index" 
end 

private def task_params 
    params.require(:task).permit(:id, :title, task_items_attributes: [:id, :item_id, :cost]) 
end 

我的观点:

<%= form_for :task, url:tasks_path do |f| %> 
<p> 
    <%= f.label :title %><br> 
    <%= f.text_field(:title, {:class => 'form-control'}) %><br> 
</p> 

<% @items.each do |item| %> 
    <% @task_items = TaskItem.new %> 
    <%= f.fields_for :task_items do |ti| %> 
     <%= ti.label item.description %> 
     <%= ti.text_field :cost %> 
     <%= ti.hidden_field :item_id, value: item.id %> 
    <% end %> 
<% end %> 

<p> 
    <%= f.submit({:class => 'btn btn-primary'}) %> 
</p> 
+0

什么是当您尝试保存'TaskItem'日志输出? – Romuloux

+1

使用render plain:params [:task] .inspect我得到了这个:“Teste 1”,“task_items”=> {“item_id”=>“4”,“cost” => “55”}}允许:假> – jtron

+1

“任务”=> { “标题”=> “Teste565656”, “task_items”=> { “ITEM_ID”=> “4”, “成本”=> “55” SQL语句(21.0ms)INSERT INTO“tasks”(“title”,“created_at”,“updated_at”)VALUES()“}”,“commit”=>“Save Contato”} 未授权参数:task_items (0.0ms)begin transaction (?,?,?,?)[[“title”,“Teste565656”],[“created_at”,2017-03-09 19:31:41 UTC],[“updated_at”,2017-03-09 19: 31:41 UTC] (122.5ms)提交事务 重定向到http://本地主机:3000/ – jtron

回答

1

您需要inverse_of选项添加到类任务的has_many方法:

class Task < ApplicationRecord 
    has_many :task_items, inverse_of: :task 
    has_many :items, through: :task_items 

    accepts_nested_attributes_for :task_items, :allow_destroy => true 
end 

创建一个新的TaskItem实例时,这是因为,它要求任务实例已经在数据库中存在能够抓住id FO任务实例。使用这个选项,它跳过验证。

您可以阅读postinverse_of选项及其使用情况。

fields_for必须指定其将要存储信息的对象的选项。这与构建has_many集合中的每个TaskItem相结合应确保所有关系都设置正确。

查看代码:

<%= form_for @task do |f| %> 
    <p> 
    <%= f.label :title %><br> 
    <%= f.text_field(:title, {:class => 'form-control'}) %><br> 
    </p> 

    <% @items.each do |item| %> 
    <% task_item = @task.task_items.build %> 
    <%= f.fields_for :task_items, task_item do |ti| %> 
     <%= ti.label item.description %> 
     <%= ti.text_field :cost %> 
     <%= ti.hidden_field :item_id, value: item.id %> 
    <% end %> 
    <% end %> 

    <p> 
    <%= f.submit({:class => 'btn btn-primary'}) %> 
    </p> 
<% end %> 

控制器代码:

def index 
end 

def new 
    @items = Item.all 
    @task = Task.new 
end 

def create 
    @task = Task.new(task_params) 
    @task.save 
    redirect_to action: "index" 
end 

private 

def task_params 
    params.require(:task).permit(:id, :title, task_items_attributes: [:id, :item_id, :cost]) 
end 
+0

它仍然说“未经允许的参数: task_items“在我的日志和task_items不会创建。我在其他地方使用inverse_of?我是否正确使用_attributes?非常感谢 – jtron