Simple_Form Association with has_many :through extra field

六月ゝ 毕业季﹏ 提交于 2019-12-04 08:30:43

问题


I have two models, Developers and Tasks,

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

im taking care of the relation by adding an Assignment table, so i can add many developers to one task in particular, now i would also like to be able to manipulate the other fields i added to the joining table like the 'estimated_time', 'accomplished_time'... etc... what i got on my Simple_form is `

<%= 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 %>`

This only allows me to select the developers, i want to be able to modify the estimated_time field right there.

Any Suggestions?


回答1:


I love how simple-form has the association helpers, making it really easy in some cases. Unfortunately, what you want you cannot solve with just simple-form.

You will have to create assignments for this to work.

There are two possible approaches.

For both you will have to add the following to your model:

class Task
  accepts_nested_attributes_for :assignments
end

Note that if you are using attr_accesible, you should also add assignments_attributes to it.

The easy approach

Suppose you know how many assignments, maximally, a task would have. Suppose 1 for simplicity.

In your controller, write

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

This will make sure there is one new assignment.

In your view write:

= 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'

The problem with this approach: what if you want more than 1, 2 or 3?

Use cocoon

Cocoon is a gem that allows you to create dynamic nested forms.

Your view would become:

= 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'

And define a partial _assignment_fields.html.haml :

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

Hope this helps.




回答2:


The thing is that by using this:

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

You're actually only setting the developer_ids attribute, which will automatically build the assignments for you as it's a has many :through. For this I believe you should probably be using nested attributes, for each of the assignments, and each record would have a select box or similar to choose the related developer for that particular assignment in this task. It's quite similar to what Cojones has answered, but you should not be using check boxes for this association, since you're going to be dealing with a single assignment which contains a single developer. And with nested attributes, you should be able to create as many assignments you want.

That I believe is the easiest way to start with.




回答3:


I think it should look somehow like this:

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


来源:https://stackoverflow.com/questions/12832546/simple-form-association-with-has-many-through-extra-field

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!