2017-03-09 7 views
1

테이블 작업 및 항목이 있습니다. 내 작업이 가지고있는 모든 가능한 항목을 기록한 Item에 대한 양식이 있는데, 이는 정상적으로 작동합니다. 그런 다음 모든 항목이 필드 옆에 표시되어 각 항목의 비용 값을 입력하는 작업에 대한 양식이 있습니다. 그러면 TaskItem (이 테이블에는 task_id, item_id 및 비용이 포함됨)과 Task : Item이 조인됩니다.레일이 중첩 된 속성을 저장하지 않습니다.

양식을 제출하면 작업이 저장되지만 관련 TaskItem은 저장되지 않습니다. 나는이 문제에 대해 많은 것을 조사 했으므로 내가 놓친 것을 보지 못했고 아무 것도 작동하지 않는 것처럼 보인다. 아래 코드를 참조하십시오.      

모델 :

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 

내보기 : 당신은 클래스 작업에 has_many 방법에 inverse_of 옵션을 추가 할 필요가

<%= 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 "}} 허용 : false> – jtron

+1

"task "=> {"title "=>"Teste565656 ","task_items "=> {"item_id "=>"4 ","cost " ("제목", "created_at", "updated_at") VALUES ("제목", "생성 된", "업데이트 됨") 허용되지 않는 매개 변수 : task_items (0.0ms) 트랜잭션 시작 SQL (21.0ms) INSERT INTO "작업" [ "title", "Teste565656"], [ "created_at", 2017-03-09 19:31:41 UTC], [ "updated_at", 2017-03-09 19 : 31:41 UTC]] (122.5ms) 커밋 트랜잭션 http : // localhost : 3000/ – jtron

답변

1

:

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 인스턴스를 만들 때이 때문이다, 그것은 작업의 인스턴스가 이미 작업 인스턴스 수 fo id를 잡아 할 수 있도록 데이터베이스에 존재해야합니다. 이 옵션을 사용하면 유효성 검사를 건너 뜁니다.

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

"Unpermitted parameter : task_items "내 로그에있는 및 task_items 만들어지지 않습니다. Shoul 나는 어디에서든지 inverse_of를 사용합니까? _attributes를 올바르게 사용하고 있습니까? 많은 감사 – jtron