1

私は次の構造を持つアイテムの単純なタグ付けシステムを持っています:

 class Item < ActiveRecord::Base
     has_many :taggings, :dependent => :destroy
     has_many :tags, :through => :taggings
 end

 class Tagging < ActiveRecord::Base
     belongs_to :tag
     belongs_to :item
 end

 class Tag < ActiveRecord::Base
     has_many :taggings, :dependent => :destroy
 end

クラスにを追加しscopeItem、特定のタグのセット(セット内のすべてのタグを含む)を持つすべてのアイテムを取得できるようにしたい

だから私は次のスコープを試しました:

 scope :tag_context, lambda { |context| (context.empty? ? all :
       joins(:taggings).where(:taggings => {tag_id => context.collect(&:id)})
       )
  }

ここcontextで、 ArrayTagオブジェクトのです。

重要なのは、このスコープが次のSQLを生成することです。

SELECT items.* FROM items INNER JOIN taggings ON taggings.item_id = items.id 
                          WHERE taggings.tag_id IN (1,2)

contextタグ1と2が含まれていると仮定します。

タグ1とタグ2でタグ付けされたアイテムを取得したいので、次のようになります。

SELECT items.* FROM items INNER JOIN taggings as t1 ON t1.item_id = items.id 
                          INNER JOIN taggings as t2 ON t2.item_id = items.id 
                          WHERE t1.tag_id = 1 AND t2.tag_id = 2

Railsスコープでそれを翻訳するにはどうすればよいですか?Itemクラスのさまざまなスコープをチェーンできるようにするには、スコープが必要です。

ご協力いただきありがとうございます!

4

1 に答える 1

1

.empty?このように動的にスコープを構築してみることができます(そして、でチェックする必要はありませんinject):

 scope :tag_context, lambda { |context| 
      context.collect(&:id).inject(self) do |m, id| 
        m.joins("INNER JOIN taggings as t#{id} ON t#{id}.item_id = items.id").
        where("t#{id}.tag_id = ?", id)
      end
 }
于 2012-08-10T17:26:52.247 に答える