2

ねえ、Rails初心者ではありませんが、これは私を困惑させました. With には、Rails のスルー アソシエーションが多数あります。このようなものを使用して、ワインリストの関連付け(または)テーブルを介して、ワインをワインバーに大量に割り当てると。

class WineBarController

  def update

    @winebar = WineBar.find(params[:id])

    @winebar.wines = Wine.find(params[:wine_bar][:wine_ids].split(","))  // Mass assign wines.

    render (@winebar.update_attributes(params[:wine_bar]) ? :update_success : :update_failure) 

  end

end

これにより、そのワインバーに関連付けられているワインリストのすべての行が削除されます。次に、wine_ids 内のすべてのワインを検索します。これは、カンマで区切られたワイン ID の文字列であると推測されます。次に、ワインリストに新しい関連付けを挿入します。これにはコストがかかりますが、破棄された関連行に個々のワイン バーのグラスやボトルあたりの価格などのメタデータが含まれていなければ問題ありません。

すべてを吹き飛ばさないようにする方法はありますか。配列の列挙可能な比較を行い、変更を挿入して削除するだけです。それはRailsが行うことのような気がしますが、明らかな何かが欠けているだけです。

ありがとう。

4

1 に答える 1

2

問題は、update メソッドの最初のステートメントにあるようです。既存のレコードを読み込んで更新するのではなく、新しいワイン バー レコードを作成しています。そのため、記録を調べても、関係を示すものは何もありません。Rails、リストのすべてのレコードをドロップ/作成しないほどスマートなので、心配する必要はありません。

フォームに標準の Rails セットアップを使用している場合:

<% form_for @wine_bar do |f| %>

次に、次のように更新を呼び出すことができます。

class WineBarController
  def update
    @winebar = WineBar.find(params[:id])
    render (@winebar.update_attributes(params[:wine_bar]) ? :update_success : :update_failure) 
  end
end

params[:wine_bar][:wine_ids]でレコードを明示的に更新する必要はありませんparams[:wine_bar]。これが役立つことを願っています!

更新:フォームのセットアップ方法が原因でこれが機能しないと述べましたが、簡単に修正できます。フォームで、入力フィールドの名前を から に変更しwine_bar[wine_ids]ますwine_bar[wine_ids_string]。次に、次のように、モデルにアクセサーを作成する必要があります。

class WineBar < ActiveRecord::Base
  def wine_ids_string
    wines.map(&:id).join(',')
  end

  def wine_ids_string= id_string
    self.wine_ids = id_string.split(/,/)
  end
end

上記の最初のメソッドは「ゲッター」です。関連するワイン ID のリストを取得し、フォームで使用できる文字列に変換します。次のメソッドは「セッター」で、コンマで区切られた ID の文字列を受け取り、それをwine_ids=受け取る配列に分割します。

私の記事Dynamic Form Elements in Railsにも興味があるかもしれません。この記事では、Rails フォーム入力がデータベース レコードの属性に限定されないことを概説しています。アクセサー メソッドの任意のペアを使用できます。

于 2010-12-13T06:04:43.043 に答える