2016-10-07 5 views
1

filterrific에서 변환 테이블의 내용을 고려하지 않는 것처럼 보입니다 (Globalize).Filterrific 및 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 몰라하지만 난의 세계화를 알고, 그리고 AR 기반으로 filterrific는 스코프 때문에 단순히해야 결과를 얻기 위해 번역 테이블에 가입하는 문제.

여기 (명확성을 위해 의견없이) 가입하고 가입 번역 테이블을 검색하도록 수정하여 search_query 범위입니다 :

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) 테이블을 쿼리의 manual_translations 테이블로 바꿨습니다. 당신이 영어 로케일에서이 쿼리를 호출하는 경우

그래서 : 그래서 당신은 단지 결과를 필터링

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'" 

공지 사항 with_translations 즉, 자동으로 manual_translations.locale = 'en'에 태그되어

Manual.search_query("foo") 

이 SQL을 얻을 당신의 로케일은 당신이 원하는 것입니다.

저에게 맞는 작품인지 알려주세요.

+0

크리스! 매력처럼 작동합니다! –

+0

좋아요! 나는'where' 질의가 필요 이상으로 복잡하다는 것을 알아 차 렸습니다. 그래서 약간 단순화되었습니다 (위 참조). –

+0

죄송합니다. 실수는 수정했습니다. 이제는 약간 더 짧게 일해야합니다. –