我的问题
创建核对清单时,如何为新核对表的作业设置初始“job_position”(checklists_jobs连接表中的列为has_may,:通过关联)?我最好的猜测是我应该使用回调(Checklists控制器中的after_filter?)。
我还需要将相同的方法应用于Update控制器操作,但我怀疑代码几乎完全相同。
用例
我正在以单一形式创建清单和关联的作业(任务)。在此表单中,用户可以创建新的清单(名称,描述),并创建新的作业(名称,描述)和/或从选择列表中选择现有的作业。
实际表单位于下面的“代码”部分,但这里是用户在创建新核对表时会看到的内容摘要:
(“添加新工作”链接) - 如果点击链接,我使用JS将新作业(空白)附加到表单:
从作业库添加作业:
创建核对清单(按钮)
在我的连接表(checklists_jobs)上,我有必要的checklist_id和job_id字段,但我还有一个“job_position”字段,它告诉我该清单上的工作的显示顺序。 (我将主要通过下面的Checklist.rb代码中显示的“unarchived_jobs”关联来完成此操作。)
它现在如何运作
现在,我没有在Checklist创建期间设置“job_position”字段,所以它只是null。用户可以通过对Checklists#Show页面上的核对表进行排序(创建核对表之后)来手动设置“job_position”。但是我想在创建核对表时为连接记录设置job_position属性,以确保在创建列表时保留/反映用户的实际定位(例如,他们添加的顺序)使用“添加新工作”链接的新工作。 注意:这是针对他们使用“添加新工作”链接添加的作业。从选择列表中选择的作业显然需要在创建核对表后由用户手动排序。
我该怎么做?
checklist.rb
class Checklist < ActiveRecord::Base
scope :archived_state, lambda {|s| where(:archived => s) }
has_many :checklists_jobs, :dependent => :destroy, :order => 'checklists_jobs.job_position'
has_many :jobs, :through => :checklists_jobs
has_many :unarchived_jobs, :through => :checklists_jobs,
:source => :job,
:conditions => ['checklists_jobs.archived = ?', false], :order => 'checklists_jobs.job_position'
end
job.rb
class Job < ActiveRecord::Base
scope :archived_state, lambda {|s| where(:archived => s)}
has_many :checklists_jobs, :dependent => :destroy
has_many :checklists, :through => :checklists_jobs
end
checklists_job.rb
class ChecklistsJob < ActiveRecord::Base
scope :archived_state, lambda {|s| where(:archived => s) }
belongs_to :job
belongs_to :checklist
attr_accessible :job_position, :job_required
end
_form.html.erb(新核对清单表格)
<%= form_for @checklist, :html => { :class => 'form-inline' } do |f| %>
<%= f.text_area :name, :rows => 1, :placeholder => 'Name the list...', :class => 'autoresizer checklist-name' %></br>
<%= f.text_area :description, :rows => 1, :placeholder => 'Optional description...', :class => 'autoresizer' %>
<%= f.fields_for :jobs, :html => { :class => 'form-inline' } do |j| %>
<%= render "job_fields", :j => j %>
<% end %>
<span class="add-new-job-link"><%= link_to_add_fields "add a new job", f, :jobs %></span>
<% unless @job_list.empty? %>
<legend>Add jobs from the Job Bank</legend>
<% @job_list.each do |job| %>
<div class="toggle">
<label class="checkbox text-justify" for="<%=dom_id(job)%>">
<%= check_box_tag "new_jobs[]", job.id, false, id: dom_id(job) %><strong><%= job.name %></strong> <small><%= job.description %></small>
</label>
</div>
<% end %>
<div class="form-actions">
<%= f.submit nil, :class => 'btn btn-primary' %>
<%= link_to 'Cancel', checklists_path, :class => 'btn' %>
</div>
<% end %>
<% end %>
答案 0 :(得分:0)
感谢朋友的建议,我使用acts_as list gem解决了这个问题。尽管我需要一些自定义调整,但实施起来还是微不足道的。默认:列是'position',所以我不得不重写它。我还需要一个自定义范围,因为我正在使用这个用于has_many,:通过连接表,我在该表中有“存档”项目(我不想在更新时订购等)。
以下是进行这些调整所需的代码行:
<强> checklists_job.rb 强>
acts_as_list :column => 'job_position', :scope => 'checklist_id = #{checklist_id} AND archived = false'
这只是添加到我最初包含在我的问题中的代码中。
#147 Sortable Lists (revised)简要提到了acts_as_list。提及的主要原因在于安装和使用的简便性。