1

1:N の関係を持つ 2 つの異なるモデルがあります。それらに「myobject」と「related」という名前を付けましょう

class Myobject < ActiveRecord::Base
  has_many :related
  scope :without_related, includes(:related).select{ |o| o.related.size == 0 }
end
class Related < ActiveRecord::Base
end

Myobjects から Related への新しい割り当てを作成しない限り、定義されたスコープはうまく機能しているようです。

  • Direct rails c コマンド "Myobject.includes(:related).select ... (Scope で定義) が期待どおりに機能する
  • スコープ「Myobject.without_related」への呼び出しは、その間に割り当てられたオブジェクトを引き続き返します

Railsコンソールの再起動やWebrickの再起動で直るそうです。しかし、オブジェクト間の関係が変更されたという理由だけで、常に Web アプリケーションを再起動できるとは限りません ;)

この問題を修正したり、より良い方法でスコープを記述する方法はありますか?

PS: このクエリは、その名前を group_method として Myobject モデルの形式で grouped_select に渡すスコープとして必要です。

4

3 に答える 3

3

あなたの問題は、実際にはあなたのスコープがスコープではないということです:)

スコープはリレーションを返す必要がありますが、スコープは配列を返します。

期待どおりに機能しますが、ラムダでラップすると

 scope :without_related, lambda{ includes(:related).select{ |o| o.related.size == 0 } }

ただし、将来このコードを使用する人を誤解させないように、このコードを通常のクラスメソッドとして書き直すことをお勧めします。

def self.without_related
  includes(:related).select{ |o| o.related.size == 0 }
end

または、他の回答でアドバイスされているように、カウンターキャッシュを使用します。

于 2012-12-18T17:50:42.683 に答える
0

または、関連するテーブルに存在する必要がある列名がわかっている場合は、次の定義を使用します。

class Myobject < ActiveRecord::Base
  has_many :related
  scope :without_related, includes(:related).where('related.id', true)
end
于 2012-12-18T17:56:49.553 に答える
0

これには counter_cache を使用することをお勧めします。int 型の列 *related_count* を Myobject に追加し、移行を行う必要があります。そうすれば、それが可能になります。

class Myobject < ActiveRecord::Base
  has_many :related
  scope :without_related, where(related_count: 0)
end

class Related < ActiveRecord::Base
  belongs_to :myobject, counter_cache: true
end

その後、関連するレコードのないすべてのオブジェクトとそのオブジェクトの数を取得するための超高速スコープが得られます

于 2012-12-18T17:46:54.427 に答える