2017-07-31 6 views
1

Railsクエリインターフェイスで次のクエリを実行しようとしていますが、ロジックを変換できません。クエリがあるrailsのクエリインターフェイスでクエリに "and"と "or"句を追加できない

Select f.* from feeds f 
Left join feed_items fi on fi.id = f.feedable_id 
where 
    f.feedable_type in ('Homework', 'Datesheet') 
    and 
    (
    (fi.assignable_type = 'Level' and assignable_id IN (1)) or 
    (fi.assignable_type = 'Student' and assignable_id IN (1)) or 
    (fi.assignable_type = 'Section' and assignable_id IN (1)) 
) 

シナリオ:

私がやっている私は

{"page"=>"1", "limit"=>"2", "type_filter"=>["Homework", "Datesheet"], "assignable_filter"=>{"Student"=>"[2]", "Section"=>"[1]", "Level"=>"[1]"}} 

これまでのところ、私のクエリで動的に追加されるフィルタを含む自分の行動にparamsハッシュを以下の受信テーブルを結合して、filter型のwhere句を追加しましたが、assignable_filtersを動的に追加する方法が不明です。ここに私のレールのコードは、optionsは、動的にクエリを構築するのないまっすぐ進む方法がありませんでした私は、レール5

+0

です。私が気づいた最初のことは、フィードとfeed_items(1対多の関係ですか?)です。 yesの場合、 'Feed.includes(:feed_items)'は正しいでしょう。 – haffla

+0

ここでは、Rails5でORクエリを実行する方法を確認できます:https://stackoverflow.com/questions/32753168/rails-5-activerecord-or-query – haffla

+0

@hafflaその1対1の関連 –

答えて

0

を使用しています

def get_feeds(options) 
    base = Feed.includes(:feed_item) 
    base = add_type_filters base, options 
    base = add_assignable_filters base, options 
    format_response base, options 
end 

def add_type_filters(base, options) 
    type_filter = options[:type_filter] 
    if !type_filter.nil? and type_filter.length > 0 
     base = base.where('feedable_type IN (?)', options[:type_filter]) 
    end 
    base 
end 

def add_assignable_filters(base, options) 
    assignable_filter = options[:assignable_filter] 
    if !assignable_filter.nil? 
     assignable_filter.each do |key, value| 
     # code for adding filters combined with or conditions 
     end 
     # wrap the or conditions and join them with an and in main where clause 
    end 
    base 
end 

P.S次のコードでparamsあります。私は問題を解決するために文字列を作成しなければなりませんでした。私の現在の解決策は

def get_feeds(options) 
    params_hash = {} 
    type_filters = add_type_filters options, params_hash 
    assignable_filters = add_assignable_filters options, params_hash 

    where = type_filters 
    where = where ? "#{where} and (#{assignable_filters})" : assignable_filters 

    base = Feed.eager_load(:feed_item).where(where, params_hash) 
    format_response base, options 
end 

def add_type_filters(options, params_hash) 
    type_filter = options[:type_filter] 
    type_filter_sql = nil 
    if !type_filter.nil? and type_filter.length > 0 
     type_filter_sql = 'feeds.feedable_type in (:type_filter)' 
     params_hash[:type_filter] = type_filter 
    end 
    type_filter_sql 
end 

def add_assignable_filters(options, params_hash) 
    assignable_filter_sql = [] 
    assignable_filter = options[:assignable_filter] 
    if !assignable_filter.nil? 
     assignable_filter.each do |key, value| 
     assignable_filter_sql.push("(feed_items.assignable_type = '#{key}' and feed_items.assignable_id IN (:#{key}))") 
     params_hash[key.to_sym] = JSON.parse(value) 
     end 
    end 
    assignable_filter_sql.join(' or ') 
end 
関連する問題