0

私の質問

チェックリストの作成時に、新しいチェックリストのジョブの最初の「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 %>
4

1 に答える 1

0

友人からの提案のおかげで、acts_as list gemを使用してこれを解決しました。いくつかのカスタム調整が必要でしたが、実装するのは簡単でした。デフォルトの :column は「位置」なので、それをオーバーライドする必要がありました。has_many, :through join テーブルにこれを使用しているため、カスタム スコープも必要でした。そのテーブルにはアイテムが「アーカイブ」されています (更新時に注文したくないなど)。

以下は、これらの調整を行うために必要なコード行です。

checklists_job.rb

acts_as_list :column => 'job_position', :scope => 'checklist_id = #{checklist_id} AND archived = false'

これは、最初に質問に含めたコードに追加するだけです。

#147 Sortable Lists (revised)は、acts_as_list について簡単に言及しています。言及は、主にインストールと使用がいかに簡単かという理由で簡単です.

于 2013-07-11T01:18:00.700 に答える