5

タスクとユーザーがいます。ユーザーがタスクを完了すると、ユーザーが費やした時間を示すフィールドを持つCompletionを作成します。すべてのタスクを完了ステータスとtime_spent属性とともに表示するフォームが必要です。送信時に、既存の補完を更新し、新しい補完を作成する必要があります。可能であればFormtasticでこれを実行したいのですが、基本的なRails3ソリューションに満足します。

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

追加の側面は、マイルストーンに属するタスクなど、特定の一連のタスクだけを表示したいということです。完了コントローラーに投稿するフォームをマイルストーンコントローラーに含める必要がありますか?

class Milestone < ActiveRecord::Base
  has_many :tasks
  has_many :completions, :through => :tasks
end

更新 私は今何日も探していました、そして私は多く 行き止まり を見つけました。Railsフォームのこの複数のオブジェクトは近いですが、すべてのリンクオブジェクトがすでに存在している必要があります。

この質問を際立たせるのは、一部のリンクがまだ存在せず、ネストされるリンクの単一のモデルがないことです。たとえば、Ryan Daigleのネストされたオブジェクトフォームの投稿)この作業を編集用のフォームで作成しましたユーザーのすべての可能な完了ですが、1つのフォームで可能な完了のサブセットを編集する必要があります。has_manyCompletionsとbelongs_toUserの冗長オブジェクトMilestoneCompletionsを作成する必要がありますか?ActiveModelはできますhas_manyか?

4

2 に答える 2

5

私はついにこれを解決しました。1つのキーは、fields_forへのコレクション引数です。もう1つは、既存のレコードと新しいレコードを組み合わせてコレクションを生成することです。

したがって、ビューでは、次のようになります。

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

ビューで、すでにDBにある完了がチェックされて無効になっているため、チェックを外すことはできません。チェックされていない状態は値「unreported」を取得し、ユーザーモデルはそれらのレコードをフィルターで除外して、DBに入らないようにすることができます。

has_many :completions
accepts_nested_attributes_for :completions, :reject_if => proc { |attrs| attrs['status'] == 'unreported' }

またcompletions_attributes、ユーザーモデルでattr_accessibleを作成する必要がありました。task_idsアクセス可能にするupdateと、から除外された補完が削除されPUTます。

于 2011-02-08T03:04:47.550 に答える
0

私は他の読者のための可能な解決策としてこれに自分で答えていますが、それは満足のいくものではないので、私はそれを許容できるものとしてマークしていません。

これを回避するために、フォーム生成アクションcreateでは、「非アクティブ」状態の関連付けが欠落しているだけです。status(モデルにフィールドを追加しますCompletion。)次に、フォームの「object[]」配列編集機能を使用します。RISCfutureには、forms_forAPIドキュメントの2番目のコメントに役立つヒントがいくつかあります。

于 2011-02-04T17:57:09.603 に答える