私の質問
チェックリストの作成時に、新しいチェックリストのジョブの最初の「job_position」(この has_may, :through 関連付けの checklists_jobs 結合テーブルの列) を設定するにはどうすればよいですか? 私の最善の推測は、コールバックを使用する必要があるということです (チェックリスト コントローラーの after_filter ?)。
これと同じメソッドを Update コントローラー アクションにも適用する必要がありますが、コードはほぼ同じになると思います。
使用事例
チェックリストと関連するジョブ (タスク) を 1 つのフォームで作成しています。このフォームから、ユーザーは新しいチェックリスト (名前、説明) を作成したり、新しいジョブ (名前、説明) を作成したり、選択リストから既存のジョブを選択したりできます。
実際のフォームは以下の「コード」セクションにありますが、新しいチェックリストを作成するときにユーザーに表示される内容の概要を次に示します。
- チェックリスト名:
- チェックリストの説明 (オプション):
(「新しいジョブを追加」リンク) - リンクをクリックすると、JS を使用して新しいジョブ (空白) をフォームに追加します。
- 職種名:
- 職務内容(オプション):
ジョブ バンクからジョブを追加します。
- (チェックボックス) 既存のジョブ 1
- (チェックボックス) 既存のジョブ 2
チェックリストの作成 (ボタン)
結合テーブル (checklists_jobs) には、必要な checklist_id フィールドと job_id フィールドがありますが、チェックリストのジョブの表示順序を示す「job_position」フィールドもあります。(私は主に、以下の Checklist.rb コードに示されている「unarchived_jobs」関連付けを介してこれを行います。)
現在の仕組み
現在、チェックリストの作成中に「job_position」フィールドを設定していないため、null になっています。ユーザーは、(チェックリストが作成された後) チェックリスト#表示ページでチェックリストをソートすることにより、「job_position」を手動で設定できます。しかし、チェックリストの作成時に結合レコードの job_position 属性を設定して、ユーザーがリストを作成したときの実際の位置(たとえば、「add newジョブ」リンク)。注:これは、「新しいジョブの追加」リンクを使用して追加したジョブ用です。選択リストから選択されたジョブは、チェックリストの作成後にユーザーが手動で並べ替える必要があることは明らかです。
どうすればいいですか?
コード
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
ジョブ.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 %>