3

counter_cacheMySQL に簿記の一部を任せるために を使用しています。

class Container
  has_many :items
end

class Item
  belongs_to :container, :counter_cache => true
end

今、私がこれを行うと:

container = Container.find(57)
item = Item.new
item.container = container
item.save

SQL ログには、次のINSERTようなものが続きます。

UPDATE `containers` SET `items_count` = COALESCE(`items_count`, 0) + 1
    WHERE `containers`.`id` = 57

これは私が期待していたことです。ただし、はcontainer[:items_count]古くなります。

...container.reload更新された値を取得しない限り。私の考えでは、特に属性reloadにアクセスしようとする前に:counter_cache を実際に必要としない可能性があるため、カスタムビルドのものを優先して :counter_cache を使用する目的の一部を無効にしitems_countます。(ドメイン ロジックの性質上、私のモデルはかなりコードが多いため、1 回のコントローラー呼び出しで複数のものを保存および作成する必要がある場合があります。)

自分でコールバックをいじることができることは理解していますが、これは単純な機能に対するかなり基本的な期待のように思えます。繰り返しになりますが、完全に機能させるために追加のコードを記述する必要がある場合は、カスタム カウンターを実装する方が簡単な場合があります。

私は何をしていますか/間違っていると思いますか?

4

2 に答える 2

3

Container インスタンスで items カウンターの値が自動的に更新されるとは思わないでください。ほとんどの Rails アプリケーションは、複数のプロセス (および多くの場合複数のサーバー) 構成で動作することに注意してください。1 つのプロセスが別のプロセスの Container インスタンスに関連付けられているアイテムを追加すると、カウンターの値は古くなります。

于 2012-11-26T01:13:43.780 に答える
1

ただし、実際にはコンテナにアイテムを認識させていません。これは、container.reload! それ。やってみました:

container = Container.find(57)
item = container.items.create()

これにより、コンテナのコンテキストでアイテムが作成され、それらの関連付けが構築されます。

于 2013-04-15T11:13:09.203 に答える