1

たとえば、次のクエリ:

SELECT `variants`.* 
  FROM `variants` INNER JOIN `variant_attributes` 
    ON variant_attributes.variant_id = variants.id 
 WHERE (variant_attributes.id IN ('2','5'))

そしてバリアントhas_manyvariant_attributes

私が実際にやりたいのは、ID =2と5の両方のバリアント属性を持つバリアントを見つけることです。これはMySQLで可能ですか?ボーナス質問、Ruby on Rails、おそらくSearchLogicでこれを行う簡単な方法はありますか?

解決

あなたが提供したクエリをQuassnoiに感謝します。それは完璧に機能しました。

Railsで使用するために、以下のnamed_scopeを使用しました。これは、初心者にとって理解しやすいと思います。

基本的にnamed_scopeは{:from => x、:conditions => y}を返し、上記の行を使用してy変数を設定しました。

  named_scope :with_variant_attribute_values, lambda { |values|
    conditions = ["(
            SELECT  COUNT(*)
            FROM    `variant_attributes`
            WHERE   variant_attributes.variant_id = variants.id
                    AND variant_attributes.value IN (#{values.collect { |value| "?" }.join ", "})
            ) = ?
    "]
    conditions = conditions + values + [values.length]
    {
    :from => 'variants', 
    :conditions => conditions
  }}
4

4 に答える 4

3

ユニークなAssiuming variant_attributes (variant_id, id)

SELECT  `variants`.*
FROM    `variants`
WHERE   (
        SELECT  COUNT(*)
        FROM    `variant_attributes`
        WHERE   variant_attributes.variant_id = variants.id
                AND variant_attributes.id IN ('2','5')
        ) = 2
于 2010-04-30T17:05:47.380 に答える
1

Quassnoiはあなたが望むことをするmysqlクエリを投稿しました。Variantこれは、同等のことを行うモデルのメソッドです。私は2つのアプローチを行っています。1つvariant_attributes (variant_id, id)は独自の組み合わせである場合、もう1つはそうでない場合です。

個性的:

class Variant < ActiveRecord::Base
  has_many :variant_attributes
  named_scope :with_variant_attributes, lamda { |*ids|
     ids = ids.flatten
     if(ids.length>0)
       result = {:include => :variant_attributes}
       sql_params = {:length => ids.length,:ids => ids}
       result[:conditions] = ["(:length = (select count(*) from variant_attributes
                                          where id in (:ids))",sql_params]
       result
     else
       nil
     end
   }
end

ユニークではない

class Variant < ActiveRecord::Base
  has_many :variant_attributes
  named_scope :with_variant_attributes, lamda { |*ids|
     ids = ids.flatten
     if(ids.length>0)
       result = {:include => :variant_attributes}
       conditions = []
       sql_params = {}

       ids.each_with_index do |id,i|
         conditions << "( 1 = Select Count(*) from variant_attributes where id = :id#{i})"
         sql_params["id#{i}"] =  id
       end
       result[:conditions] = [ '(' + conditions.join(' AND ') + ')', sql_params]
       result
     else
       nil
     end
   }
end

これは次のように使用できます。

# Returns all Variants with variant_attributes 1, 2, & 3
vars = Variant.with_variant_attributes(1,2,3) 

# Returns Variant 5 if it has attributes 3 & 5, or null if it doesn't
vars = Variant.with_variant_attributes(3,5).find_by_id(5)

#Returns Variants between 1 and 20 if that have an attribute of 2
vars = Variant.with_variant_attributes(2).find(:conditions => "id between 1 and 20")

#can accept a variable array of ids
my_ids = [3,5]
vars = Variant.with_variant_attributes(my_ids)

このコードはテストされていません。

于 2010-04-30T19:06:58.647 に答える
0

このためにnamed_scopeを作成します。

class Variant < ActiveRecord::Base
  has_many    :variant_attributes

  named_scope :with_variant_attributes, lambda { |*ids| { 
            :joins => :variant_attributes, 
            :conditions => {:variant_attributes=>{:id=>ids}},
            :group => "variants.id",
            :having => "count(variants.id) = #{ids.size}"
            }
          }
end

これで、名前付きスコープを次のように使用できます。

Variant.with_variant_attributes(1,2)
Variant.with_variant_attributes(1,2,3,4)
于 2010-04-30T22:13:05.363 に答える
0

あなたが提供したクエリをQuassnoiに感謝します。それは完璧に機能しました。

Railsで使用するために、以下のnamed_scopeを使用しました。これは、初心者にとって理解しやすいと思います。

基本的にnamed_scopeは{:from => x、:conditions => y}を返し、上記の行を使用してy変数を設定しました。

  named_scope :with_variant_attribute_values, lambda { |values|
    conditions = ["(
            SELECT  COUNT(*)
            FROM    `variant_attributes`
            WHERE   variant_attributes.variant_id = variants.id
                    AND variant_attributes.value IN (#{values.collect { |value| "?" }.join ", "})
            ) = ?
    "]
    conditions = conditions + values + [values.length]
    {
    :from => 'variants', 
    :conditions => conditions
  }}
于 2010-05-09T14:58:09.543 に答える