2016-10-07 7 views
1

filterrificが変換テーブルの内容を考慮に入れているように見えます(Globalize)。Filterrific and Globalize

とにかく変換​​テーブルも検索しますか?コンテンツが実際のモデルにある場合は、私の設定はうまくいきます。ただし、フィールドが空で変換テーブルにのみ入力されても、結果は表示されません(明らかに)。

マイモデル:

class Manual < ApplicationRecord 
    translates :title, :content, :teaser, :slug 

    extend FriendlyId 
    friendly_id :title, :use => :globalize 

    belongs_to :user 
    belongs_to :support_category 
    has_many :manual_faqs 
    has_many :faqs, :through => :manual_faqs 

    validates :title, presence: true 
    validates :content, presence: true 
    validates :user_id, presence: true 

    update_index('manuals#manual') { self } 

    filterrific(
     default_filter_params: { sorted_by: 'created_at_desc' }, 
     available_filters: [ 
      :sorted_by, 
      :search_query, 
      :with_user_id, 
      :with_created_at_gte 
     ] 
) 

    scope :with_user_id, lambda { |user_ids| 
    where(user_id: [*user_ids]) 
    } 

    scope :search_query, lambda { |query| 
    # Searches the students table on the 'first_name' and 'last_name' columns. 
    # Matches using LIKE, automatically appends '%' to each term. 
    # LIKE is case INsensitive with MySQL, however it is case 
    # sensitive with PostGreSQL. To make it work in both worlds, 
    # we downcase everything. 
    return nil if query.blank? 

    # condition query, parse into individual keywords 
    terms = query.downcase.split(/\s+/) 

    # replace "*" with "%" for wildcard searches, 
    # append '%', remove duplicate '%'s 
    terms = terms.map { |e| 
     ('%' + e.gsub('*', '%') + '%').gsub(/%+/, '%') 
    } 
    # configure number of OR conditions for provision 
    # of interpolation arguments. Adjust this if you 
    # change the number of OR conditions. 
    num_or_conds = 2 
    where(
     terms.map { |term| 
      "(LOWER(manuals.title) LIKE ? OR LOWER(manuals.content) LIKE ?)" 
     }.join(' AND '), 
     *terms.map { |e| [e] * num_or_conds }.flatten 
    ) 
    } 

    scope :sorted_by, lambda { |sort_option| 
    # extract the sort direction from the param value. 
    direction = (sort_option =~ /desc$/) ? 'desc' : 'asc' 
    case sort_option.to_s 
     when /^created_at_/ 
     # Simple sort on the created_at column. 
     # Make sure to include the table name to avoid ambiguous column names. 
     # Joining on other tables is quite common in Filterrific, and almost 
     # every ActiveRecord table has a 'created_at' column. 
     order("manuals.created_at #{ direction }") 
     else 
     raise(ArgumentError, "Invalid sort option: #{ sort_option.inspect }") 
    end 
    } 

    scope :created_at_gte, lambda { |reference_time| 
    where('manuals.created_at >= ?', reference_time) 
    } 

    def self.options_for_sorted_by 
    [ 
     ['Date received (newest first)', 'created_at_desc'], 
     ['Date received (oldest first)', 'created_at_asc'] 
    ] 
    end 
end 

マイコントローラー:

def index 
    @filterrific = initialize_filterrific(
     Manual, 
     params[:filterrific], 
     select_options: { 
      sorted_by: Manual.options_for_sorted_by, 
      with_user_id: User.options_for_select 
     } 
    ) or return 

    @manuals = @filterrific.find.page(params[:page]) 

    respond_to do |format| 
     format.html 
     format.js 
    end 

    rescue ActiveRecord::RecordNotFound => e 
    # There is an issue with the persisted param_set. Reset it. 
    puts "Had to reset filterrific params: #{ e.message }" 
    redirect_to(reset_filterrific_url(format: :html)) and return 
    #respond_with(@references) 
    end 

答えて

1

私はまったくfilterrificを知らないが、私はグローバル化知っている、とfilterrific以来、ARに基づいていますが、それは単にあるべきスコープ結果を得るために翻訳テーブルに参加することの問題。

ここで(明確にするため、コメントせずに)参加した翻訳テーブルを結合して検索するように変更あなたの​​範囲です:私は二つのことをのみ変更した

scope :search_query, lambda { |query| 
    return nil if query.blank? 

    terms = query.downcase.split(/\s+/) 

    terms = terms.map { |e| 
    ('%' + e.gsub('*', '%') + '%').gsub(/%+/, '%') 
    } 

    num_or_conds = 2 
    where(
    ('(LOWER(manual_translations.title) LIKE ? OR'\ 
    ' LOWER(manual_translations.content) LIKE ?)' * (terms.count)).join(' AND '), 
    *terms.map { |e| [e] * num_or_conds }.flatten 
).with_translations 
} 

お知らせ:(1)私はwith_translationsを追加しましたが、現在のロケールの翻訳を結合するメソッドdescribed in this SO answerと、(2)manualsテーブルをクエリのmanual_translationsテーブルと入れ替えました。

ですから、英語ロケールでこのクエリを呼び出す場合:with_translationsは自動的にそのmanual_translations.locale = 'en'にタグ付けされたので、あなたは結果のみをフィルタリングすることを

SELECT "manuals".* FROM "manuals" 
INNER JOIN "manual_translations" ON "manual_translations"."manual_id" = "manuals"."id" 
WHERE (LOWER(manual_translations.title) LIKE '%foo%' OR 
     LOWER(manual_translations.content) LIKE '%foo%') 
     AND "manual_translations"."locale" = 'en'" 

は予告:

Manual.search_query("foo") 

を、あなたは、このSQLを取得しますあなたのロケールは、あなたが望むものです。

それがあなたに役立つかどうか教えてください。

+0

ありがとうChris!魅力的な作品! –

+0

素晴らしい!私は、 'where'クエリが必要以上に複雑であることに気づいたので、少し単純化しました(上記参照)。 –

+0

申し訳ありませんが、間違いを修正しました。今すぐ動作するはずですが、少し短くなりました。 –

関連する問題