Tur*_*adg 5 activerecord ruby-on-rails nested-sets nested-forms
我有任务和用户.当用户完成任务时,我创建一个完成,其中有一个字段供用户指示他们花了多长时间.我需要一个表单,显示所有具有完成状态和time_spent属性的任务.在提交时,应更新已存在的完成,并应创建新的完成.如果可能的话,我想在Formtastic中这样做,但我会对基本的Rails 3解决方案感到满意.
class Completion < ActiveRecord::Base
belongs_to :task
belongs_to :user
# attribute time_spent
end
class User < ActiveRecord::Base
has_many :completions
has_many :tasks, :through => :completions
end
class Task < ActiveRecord::Base
belongs_to :milestone
has_many :completions
has_many :users, :through => :completions
end
Run Code Online (Sandbox Code Playgroud)
另一个方面是我想要显示一组特定任务,例如那些属于里程碑的任务.我应该在里程碑控制器上有一个表格发布到完成控制器吗?
class Milestone < ActiveRecord::Base
has_many :tasks
has_many :completions, :through => :tasks
end
Run Code Online (Sandbox Code Playgroud)
更新 我现在已经找了几天,我发现了很多 死路 一条.Rails表单中的这个Multiple对象很接近,但它要求所有链接对象都已存在.
让这个问题与众不同的是,有些链接尚不存在,并且没有单一的模型可以嵌套链接.例如,使用Ryan Daigle的嵌套对象形式帖子)我已经将这个工作以一种形式进行编辑所有可能的用户完成,但我需要在一个表单中编辑可能的完成的子集.我是否需要制作一个冗余对象MilestoneCompletions即has_manyCompletions和belongs_toUser?可以使用ActiveModel has_many吗?
我终于解决了这个问题 一个关键是fields_for的集合参数.另一种是使用现有记录和新记录的混合生成集合.
所以在视图中,类似于:
<%= form_for @user do |f| %>
<table>
<tr><th>Completed</th><th>Time spent</th><th>Task</th></tr>
<%= f.fields_for :completions, available_completions_for_milestone(@user, @milestone) do |cf| %>
<tr>
<td><%= cf.check_box :status, {disabled: cf.object.persisted?}, "done", "unreported" %></td>
<td><%= cf.text_field :time_spent_text %></td>
<td><%= cf.object.task.description %></td>
</tr>
<%= cf.hidden_field :task_id %>
<% end -%>
Run Code Online (Sandbox Code Playgroud)
使用辅助方法:
def available_completions_for_milestone(user, milestone)
user_completions = user.completions.in_milestone(milestone)
available = []
milestone.tasks.each do |t|
c = user_completions.select{|c| c.task_id == t.id}.first
if !c then # make it
c = user.completions.build( task: t )
end
available << c
end
available
end
Run Code Online (Sandbox Code Playgroud)
请注意,在视图中已经检查并禁用了DB中已有的完成,因此无法取消选中它们.未选中状态获取值"未报告",用户模型可以过滤掉这些记录,以便它们不会进入数据库:
has_many :completions
accepts_nested_attributes_for :completions, :reject_if => proc { |attrs| attrs['status'] == 'unreported' }
Run Code Online (Sandbox Code Playgroud)
我还必须completions_attributes在User模型上创建attr_accessible.如果你可以task_ids访问,那么update将删除遗漏的完成PUT.
| 归档时间: |
|
| 查看次数: |
945 次 |
| 最近记录: |