簡體   English   中英

Rails 4嵌套屬性和has_many:通過表單中的associaton

[英]Rails 4 nested attributes and has_many :through associaton in a form

我在管理has_many時遇到問題:通過使用表單進行關聯。 我不想做的是編輯相關模型的屬性,其中有大量信息,而我只想管理關聯。 我理解我可以通過操作傳遞給我的操作的表單參數並手動構建關系來做到這一點,但我更願意采用Rails方式,如果可能的話。

關於我的一個有趣的事情是,這個has_many:通過關聯實際上是一個模型,我已經使用accepts_nested_attributes_for保存了

以下是我的模型:目標,里程碑和程序。

class Goal < ActiveRecord::Base
  has_many :milestones, inverse_of: :goal, dependent: :destroy
  accepts_nested_attributes_for :milestones, :allow_destroy => true
end

class Milestone < ActiveRecord::Base
  belongs_to :goal, inverse_of: :milestones

  has_many :milestone_programs
  has_many :programs, :through => :milestone_programs
end

class Program < ActiveRecord::Base
end

現在,在我的目標編輯視圖中,我需要能夠添加和刪除里程碑,對於那些里程碑,我需要能夠添加和刪除程序關聯。 這是我表單的代碼。

<%= form_for @goal do |f| %>

  <%= f.fields_for :milestones do |f_milestone| %>

    <%= f.hidden_field :id, :value => f.object.id %>
    <%= f.hidden_field :name, :value => f.object.name %>
    <a href="javascript:void(0)" class="milestone-remove">- remove</a>

    <ul>
      <%= f.fields_for :programs do |f_prog| %>
        <li>
          <%= f_prog.object.name %>
          <a href="javascript:void(0)" class="program-remove">- remove</a>
        </li>
      <% end %>
    </ul>

  <% end %>

  <%= f.submit 'Save' %>

<% end %>

在我的控制器中,我有

class GoalsController < ApplicationController

    # PATCH/PUT /goals/:id
    def update
      if @goal.update(goal_params)
        redirect_to @goal
      end
    end

    def goal_params
      params.require(:goal).permit(:name, :milestones_attributes => [ :id, :name, :_destroy ])
    end

end

此表單必須像工作表,您可以在其中進行更改,並且只在最后單擊保存時保存更改,因此我不相信諸如cocoon或nested_forms之類的gem會有所幫助。

到目前為止,我的代碼完美地用於管理我的目標相關里程碑及其屬性。 但現在我希望能夠管理與這些里程碑相關的程序列表。

我嘗試過使用accepts_nested_attributes_for,但這並不是我想要的,因為我不關心編輯模型的嵌套屬性,Program屬性要保持靜態。

我想我可能會在每個程序的表單中都有這樣的東西來構建關聯:

<input type="hidden" name="goal[milestones_attributes][1][program_ids][1]" >

但這也不起作用(當然我已經添加了:program_ids到我列入白名單的參數)。 我需要添加到控制器中的魔術軌道方法嗎?

我在這里錯過了什么?

提前致謝!

使用has_many :through關系時,需要通過不同的模型傳遞nested_attributes ,如下所示:

楷模

class Goal < ActiveRecord::Base
  has_many :milestones, inverse_of: :goal, dependent: :destroy
  accepts_nested_attributes_for :milestones, :allow_destroy => true

  def self.build
      goal = self.new
      goal.milestones.build.milestone_programs.build_program
  end
end

class Milestone < ActiveRecord::Base
  belongs_to :goal, inverse_of: :milestones

  has_many :milestone_programs
  has_many :programs, through: :milestone_programs

  accepts_nested_attributes_for :milestone_programs
end

class MilestoneProgram < ActiveRecord::Base
    belongs_to :milestone
    belongs_to :program

    accepts_nested_attributes_for :program
end

class Program
    has_many :milestone_programs
    has_many :milestones, through: :milestone_programs
end

調節器

#app/controllers/goals_controller.rb
def new
    @goal = Goal.build
end

def create
    @goal = Goal.new(goal_params)
    @goal.save
end

private

def goal_params
    params.require(:goal).permit(milestones_attributes: [milestone_programs_attributes: [program_attributes:[]]])
end

形成

#app/views/goals/new.html.erb
<%= form_for @goal do |f| %>
   <%= f.fields_for :milestones do |m| %>
      <%= m.fields_for :milestone_programs do |mp| %>
          <%= mp.fields_for :program do |p| %>
               <%= p.text_field :name %>
          <% end %>
      <% end %>
   <% end %>
   <%= f.submit %>
<% end %>

我很欣賞這可能不是你想要的,但是我沒有閱讀你所有的散文。 我剛剛收集了你需要幫助通過has_many :through關系傳遞nested_attributes

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM