ruby-on-rails - 如何显示关联记录子集的表单,其中一些尚不存在?

标签 ruby-on-rails activerecord nested-forms nested-sets

我有任务和用户。当用户完成一项任务时,我会创建一个 Completion,其中有一个字段供用户指示他们花费了多长时间。我需要一个表格来显示所有任务的完成状态和 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

一个额外的方面是我只想显示一组特定的任务,例如属于里程碑的任务。我应该在 Milestone Controller 上有一个表单来发布到 Completions Controller 吗?
class Milestone < ActiveRecord::Base
  has_many :tasks
  has_many :completions, :through => :tasks
end

更新
我已经找了好几天了,我找到了 many dead ends .
Multiple objects in a Rails form很接近,但它要求所有链接对象都已经存在。

使这个问题与众不同的是,某些链接尚不存在,并且没有用于嵌套链接的单一模型。例如与 Ryan Daigle 的 Nested Object Forms post ) 我以一种形式完成了这项工作,以编辑用户的所有可能的完成,但我需要以一种形式编辑可能的完成的子集。我是否需要创建一个冗余对象 MilestoneCompletions,该 has_many完成和 belongs_to用户?可以使用 ActiveModel has_many ?

最佳答案

我终于解决了这个问题。一个键是 fields_for 的集合参数.另一种方法是使用现有记录和新记录混合生成集合。

所以在 View 中,类似于:

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

使用辅助方法:
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

请注意,在 View 中已选中并禁用数据库中已有的完成,因此无法取消选中它们。 unchecked 状态的值是“unreported”,用户模型可以过滤掉这些记录,这样它们就不会进入数据库:
has_many :completions
accepts_nested_attributes_for :completions, :reject_if => proc { |attrs| attrs['status'] == 'unreported' }

我也不得不做 completions_attributes用户模型上的 attr_accessible。如果您制作 task_ids然后可以访问 update将删除被排除在 PUT 之外的补全.

关于ruby-on-rails - 如何显示关联记录子集的表单,其中一些尚不存在?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4876317/

相关文章:

ruby-on-rails - 使用单个模型创建多个资源

ruby-on-rails - 删除用户帐户后如何重置 omniauth-google-oauth2 access_token

ruby-on-rails - 如何使用 i18n 本地化 Stimulus JS 值?

ruby-on-rails - 如何从父 Controller 保存我的子记录?

ruby-on-rails - Rails 4 中的嵌套表单未在 View 中呈现

ruby-on-rails - 在 Rails 中将多级嵌套表单标记为 "dirty"

Mysql 5.7 json 数据类型,在 Rails 5 中使用 activerecord 查询

php - Kohana ORM - 我该怎么做?

ruby-on-rails - 如何正确转义 Active Record where 子句中的正则表达式

mysql - ActiveRecord 连接和位置