【问题标题】:Simple_Form Association with has_many :through extra fieldSimple_Form 与 has_many 的关联:通过额外的字段
【发布时间】:2012-10-01 16:53:12
【问题描述】:

我有两个模型,开发者和任务,

class Developer < ActiveRecord::Base
  attr_accessible :address, :comment, :email, :name, :nit, :phone, :web
  has_many :assignments
  has_many :tasks, :through => :assignments
end

class Task < ActiveRecord::Base
  attr_accessible :description, :name, :sprint_id, :developer_ids
  has_many :assignments
  has_many :developers, :through => :assignments
end

class Assignment < ActiveRecord::Base
  attr_accessible :accomplished_time, :developer_id, :estimated_time, :status, :task_id
  belongs_to :task
  belongs_to :developer
end

我通过添加分配表来处理关系,因此我可以将许多开发人员特别添加到一项任务中,现在我还希望能够操作我添加到连接表中的其他字段,例如“estimated_time” ','accomplished_time'......等等......我在Simple_form上得到的是 `

<%= simple_form_for [@sprint,@task], :html => { :class => 'form-horizontal' } do |f| %>
  <%= f.input :name %>
  <%= f.input :description %>
  <%= f.association :developers, :as => :check_boxes %>

  <div class="form-actions">
    <%= f.button :submit, :class => 'btn-primary' %>
    <%= link_to t('.cancel', :default => t("helpers.links.cancel")),
                project_sprint_path(@sprint.project_id,@sprint), :class => 'btn' %>
  </div>
<% end %>`

这仅允许我选择开发人员,我希望能够在此处修改estimated_time 字段。

有什么建议吗?

【问题讨论】:

    标签: ruby-on-rails ruby-on-rails-3 associations has-many-through simple-form


    【解决方案1】:

    我认为它应该看起来像这样:

    = f.simple_fields_for :assignments do |fa|
      = fa.association :developer, as: :check_boxes
      = fa.input :estimated_time
      ...
    

    【讨论】:

    • 它不工作,它返回一个错误关联不能用于与对象不关联的表单中提取的源(在第 6 行附近):3: 4: 5: 6: 7: 8: 9: :check_boxes %>
    • 关联应该是:developer(单数),所以=fa.association :developer, :as =&gt; ...
    • 但这仍然不是我想要的
    【解决方案2】:

    问题是通过使用这个:

    <%= f.association :developers, :as => :check_boxes %>
    

    您实际上只是设置了 developer_ids 属性,它会自动为您构建分配,因为它有很多 :through。为此,我相信您可能应该为每个作业使用嵌套属性,并且每条记录都会有一个选择框或类似的东西来为该任务中的特定作业选择相关开发人员。这与 Cojones 的回答非常相似,但您不应该为此关联使用复选框,因为您将处理包含单个开发人员的单个任务。并且使用嵌套属性,您应该能够创建任意数量的分配。

    我认为这是最简单的开始方式。

    【讨论】:

      【解决方案3】:

      我喜欢 simple-form 具有关联助手的方式,这在某些情况下非常容易。不幸的是,您想要的只是简单的形式无法解决。

      您必须创建 assignments 才能使其正常工作。

      有两种可能的方法。

      对于这两种情况,您都必须将以下内容添加到您的模型中:

      class Task
        accepts_nested_attributes_for :assignments
      end
      

      请注意,如果您使用的是attr_accesible,您还应该在其中添加assignments_attributes

      简单的方法

      假设您知道task 最多有多少个分配。为简单起见,假设为 1。

      在你的控制器中,写

      def new
        @task = Task.build
        @task.assignments.build
      end
      

      这将确保有一个新任务。

      在你看来写:

      = simple_form_for [@sprint,@task], :html => { :class => 'form-horizontal' } do |f| 
        = f.input :name 
        = f.input :description 
      
        = f.simple_fields_for :assignments do |assignment|
          = assignment.association :developer, :as => :select
          = assignment.estimated_time
      
        .form-actions
          = f.button :submit, :class => 'btn-primary'
          = link_to t('.cancel', :default => t("helpers.links.cancel")),
                      project_sprint_path(@sprint.project_id,@sprint), :class => 'btn'
      

      这种方法的问题:如果您想要超过 1、2 或 3 个怎么办?

      使用茧

      Cocoon 是一个允许您创建动态嵌套表单的 gem。

      你的观点会变成:

      = simple_form_for [@sprint,@task], :html => { :class => 'form-horizontal' } do |f| 
        = f.input :name 
        = f.input :description 
      
        = f.simple_fields_for :assignments do |assignment|
          = render `assignment_fields`, :f => assignment
        .links
          = link_to_add_association 'add assignment', f, :assignments
      
        .form-actions
          = f.button :submit, :class => 'btn-primary'
          = link_to t('.cancel', :default => t("helpers.links.cancel")),
                      project_sprint_path(@sprint.project_id,@sprint), :class => 'btn'
      

      并定义一个部分_assignment_fields.html.haml

      .nested_fields
        = f.association :developer, :as => :select
        = f.estimated_time
        = link_to_remove_association 'remove assignment', f
      

      希望这会有所帮助。

      【讨论】:

      • 嗨,Nathan,我尝试使用 cocoon,但我不知道应该在我的模型或控制器中更改什么,因为它无法识别分配。这是错误 C:/Users/Gaspar/Desktop/vkanban2/app/views/tasks/_assignment_fields.html.erb 其中第 1 行引发:未定义的局部变量或方法 `assignment' for #: 0x590cd90> 提取的源代码(第 1 行附近):1::select %> 2: 3:
      • 哦,是的,剪切和粘贴错误。这段代码当然是未经测试的。显然,错误表明变量assignment 在部分中是未知的,实际上,在渲染中我传递了一个名为f 的变量。所以你应该写f.association而不是assignment.association。我相应地编辑了我的答案。
      • 我猜测应该是 f.association 而不是 assignment.association 但这仍然无法识别变量
      • 在您的模型中,您需要添加accepts_nested_attributes_for :assignments 才能使其正常工作。还要确保 cocoon.js 包含在 javascripts 列表的最后。
      • 你或者茧的github页面为什么不包含“”?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-11-27
      • 1970-01-01
      • 1970-01-01
      • 2012-05-16
      相关资源
      最近更新 更多