2

簡単に言えば、連絡先には、スケジュールとしてアクティブである場合とそうでない場合がある、さまざまな関連付けられたタイム ウィンドウを設定できます。ウィット:

モデル

class Contact < ActiveRecord::Base
  has_many :schedules
  has_many :time_windows, :through => :schedules
  accepts_nested_attributes_for :schedules, :allow_destroy => true
end

class TimeWindow < ActiveRecord::Base
  has_many :schedules
  has_many :contacts, :through => :schedules
end

class Schedule < ActiveRecord::Base
  belongs_to :contact
  belongs_to :time_window
end

意見

  <% TimeWindow.all.each do |tw| %>
    <% schedule = Schedule.find_by_contact_id_and_time_window_id(@contact.id, tw.id)
       schedule ||= Schedule.new %>
    <p>
      <%= f.label tw.description %>
      <%= hidden_field_tag "contact[schedules_attributes][][id]", schedule.id %>
      <%= check_box_tag "contact[schedules_attributes][][time_window_id]",
 tw.id, @contact.time_windows.include?(tw) %>
      <%= check_box_tag "contact[schedules_attributes][][active]", nil,
 schedule.active %>
    </p>
  <% end %>

これは次のようなものを提出します:

Parameters: { "commit" => "Update", "contact" => {
  "group_ids" => ["2"], "enabled" => "1",
  "schedules_attributes" => [ { "time_window_id"=>"1", "id"=>"46"},
   { "time_window_id" => "2", "id" => "42", "active" => "on" },
   { "time_window_id" => "3", "id" => "43"},
   { "time_window_id" => "4", "id" => "44", "active" => "on"}],
  "last_name" => ... 

コントローラーの更新アクションは、基本的にストックされていますが、Advanced Rails Recipes ブックの「Handling Multiple Models」の例を使用してコーディングした、別の関連モデルの別のインスタンスを処理することを除きます。

この API docによると、上記は機能するはずです。ただし、スケジュールについては何も更新されていません。これはサーバー ログに表示されます。

  [4;35;1mSchedule Update (0.2ms)[0m   [0mUPDATE `schedules` SET `updated_at` = '2010-09-30 20:39:49', `active` = 0 WHERE `id` = 42[0m
  [4;36;1mSchedule Update (0.1ms)[0m   [0;1mUPDATE `schedules` SET `updated_at` = '2010-09-30 20:39:49', `active` = 0 WHERE `id` = 44[0m

(NetBeans は出力に愚かな "[0m" を表示しています。何が問題なのかわかりません。)

SQL は、「アクティブな」ブール フィールドがチェックされた場所で 0 に設定されていることを示しています。アクティブビットを正しく設定するにはどうすればよいですか?

フォローアップとして、スケジュールの「接続」をまったく取り除くためにこれをどのように整理しますか? フォームからスケジュールを指定して :_delete を送信する必要があると考えていますが、チェックボックスが関係している場合、条件付きでそれを行うにはどうすればよいですか?

ご協力いただきありがとうございます。Rails は私にとって広大な主題であることが判明しており、「正しく」やりたいと思っています。私はここに本当に近づいていますが、これを正しいだけでなくエレガントにする方法が必要です。ビューのコードは、適切な Rails であるにはあまりにも面倒に感じます。;-)

4

1 に答える 1

0

私はこの問題に対してさまざまなアプローチを試み続けてきましたが、うまくいくこれを思いつきました。多くの場合。唯一の問題は、「タイム ウィンドウ」ごとに「スケジュール」がないことを処理できないことです。フォームがレンダリングされ、無効になっている check_box が表示されます (そこにないものを削除しようとするのを防ぐため)。ハッシュ(そしてRailsから「予想されるハッシュ(配列を取得)」エラーが表示されます)

<% TimeWindow.all.each do |tw| %>
  <% schedule = Schedule.find_by_contact_id_and_time_window_id(@contact.id, tw.id)
     schedule ||= Schedule.new %>

<% f.fields_for "schedules_attributes[]", schedule do |sf| %>
  <p>
    <%= sf.label tw.description %>
    <%= sf.hidden_field :id %>
    <%= sf.check_box :_destroy, :disabled => schedule.new_record? %>
    <%= sf.check_box :active %>
  </p>
<% end %>

<% end %>

「schedules_attributes[]」配列は、HTML の中括弧内に既存の ID を自動的に提供しますが (これは素晴らしいことです)、_attributes ハッシュは、サブを理解​​するために他の属性と一緒に「id」を想定していることに注意してください。 -ハッシュ。

ここで私が学んだ大きな教訓の 1 つは、"check_box_tag" メソッドは、Rails がチェックされていない場合に解析するための対になった隠しフィールドを提供しない (ように見える) ということです。私はこれを期待していたでしょう。手動で 1 つ追加すると混乱が生じ、最終的に「fields_for」メソッドに屈し、適切な構文を見つける前に多くの具体化を試みて、そこから必要なものを取得しました。

私のモデルはこのセットアップではあまり適切ではないことに気付いたので、変更しますが、この答えに非常に近かったので、少なくとも最後まで見ることができるようになりたいと思っていました先に進む前に。

于 2010-10-01T18:07:51.527 に答える