2017-12-23 8 views
0

여러 범위를 함께 연결하는 방법을 알아 내려고하고 있습니다. 내가하려는 일은 사용자 모델에서 by_keyword 범위를 호출하는 컨트롤러에 params [: user_search]를 전달하는 검색 상자를 갖는 것입니다. 내가 지금 가지고있는 by_keyword 범위가 작동하지만 다른 모든 범위를 검색하도록하고 싶습니다. 그러므로 본질적으로 by_keyword 범위는 사용자가 입력 한 키워드에 상관없이 모든 범위를 쿼리해야합니다. 내 사용자 모델에서 내 users_controller 지수 액션Rails - 연결 범위에 인수 전달

if params[:user_search].present? 
    @users = @users.by_keyword(params[:user_search]) 
    end  

에서

내가

scope :by_keyword, -> (keyword) { where('experience LIKE ? OR current_job_title LIKE ?', "%#{keyword}%", "%#{keyword}%").order(updated_at: :desc) if keyword.present? } 

내가 by_keyword 범위

# these scopes call child classes of User such as skills, languages, patents, etc... 

    scope :by_skill, -> (sk) { joins(:skills).distinct.where('skills.name LIKE ?', "%#{sk}%").order(updated_at: :desc) if sk.present? } 
    scope :by_language, -> (lang) { joins(:languages).distinct.where('languages.language LIKE ?', "%#{lang}%").order(updated_at: :desc) if lang.present? } 
    scope :by_certification_or_cert_authority, -> (cert) { joins(:certifications).distinct.where('certifications.certification_name LIKE ? OR certifications.certification_authority LIKE ?', "%#{cert}%", "%#{cert}%").order(updated_at: :desc) if cert.present? } 
    scope :by_education_level, -> (ed) { joins(:qualifications).distinct.where('qualifications.education LIKE ?', "%#{ed}%").order(updated_at: :desc) if ed.present? } 
    scope :by_university_major, -> (maj) { joins(:qualifications).distinct.where('qualifications.university_major LIKE ?', "%#{maj}%").order(updated_at: :desc) if maj.present? } 
이러한 모든 체인 방법을 찾고 싶습니다있다

내가 읽음 http://guides.rubyonrails.org/active_record_querying.html#scopes

그리고이 예제는이 예제이지만, 함께 연결된 2 개 이상의 스코프로이 작업을 수행하는 방법을 잘 모르겠습니다.

class Article < ApplicationRecord 
    scope :published,    -> { where(published: true) } 
    scope :published_and_commented, -> { published.where("comments_count > 0") } 
end 

답변

0
당신은

def self.send_chain(methods) 
    methods.inject(self, :send) 
end 

그 다음이로 전송하고 그것을 사용자 모델에서 here

같은 배열을 제공 호출 사용자 PLC의 기능을 할

User.send_chain(["by_skill", "by_language"]) 
처럼 호출 할 수 있습니다

params를 보내야하는 경우 다음과 같이 할 수 있습니다.

scopes = ["by_skill", "by_language"] 
parameters = ["clever", "English"] 
result = [] 
scopes.each_with_index do |scope, index| 
    result = result + User.send(scope, parameters[index]) 
end 

희망이 도움이됩니다.

+0

내 모든 스코프는 인수를 받지만, 스코프에 인수를 전달하는 방법은 확실하지 않습니다. – Scott

+0

흠, 두 개의 배열을 만들어 다른 아이디어를 얻었습니다. 첫 번째 배열은 범위의 이름으로 구성되고, 두 번째 배열은 범위의 매개 변수로 구성됩니다. 배열 인덱스 간의 일대일 관계와 같을 것입니다. index each_with_index와 함께 첫 번째 배열을 만들고 [send] (https://ruby-doc.org/core-2.2.0/Object)를 적용합니다.html # method-i-send) 함수를 사용하여 두 번째 배열에있는 매개 변수를 보내고 결과를 일부 변수에 보관합니다. 실제로 범위를 원하는 방식으로 연결할 수 있는지 여부는 알 수 없습니다. 최대한 빨리 솔루션을 찾으십시오. –

0

이 시도 :이 정말 생각 "체인"을 고려하면

scope :all_clild, -> (val) { |val| by_skill(val).or.by_language(val).or.by_certification_or_cert_authority(val).........# all other scopes} 

merged_scope = by_keyword.merge(all_clild) 
+0

예기치 않은 "|"오류 구문 오류가 발생합니다. 나는 그것을 좋아하지 않는다고 생각한다. | val | – Scott

+0

다시 시도해주세요. 업데이트했습니다. –

0

내가 잘 모르겠어요이

scope :by_keyword, -> (k) { by_skill(k) | by_language(k) | by_certification_or_cert_authority(k) | by_education_level(k) | by_university_major(k)} 

같은 범위에 인수를 전달할 수 있었다. 나에게 알려주는 것이 있다면 아마도 이것을하는 더 좋은 방법이있을 것이라고 생각합니다.

많은 수의 쿼리를 작성하므로이 스코프를 현명한 방식으로 호출하는 것이 현명한 성능을 발휘하는지 확실하지 않습니다. 그것은 사용자가 많은 테이블을 접촉 한 쿼리를 입력 할 수 있도록 모든 좋은 경우 잘 모르겠어요 보안 관점에서 용어 "CCNA"또한

User Load (0.5ms) SELECT DISTINCT "users".* FROM "users" INNER JOIN "skills" ON "skills"."user_id" = "users"."id" WHERE (skills.name LIKE '%CCNA%') ORDER BY "users"."updated_at" DESC 
    User Load (0.5ms) SELECT DISTINCT "users".* FROM "users" INNER JOIN "languages" ON "languages"."user_id" = "users"."id" WHERE (languages.language LIKE '%CCNA%') ORDER BY "users"."updated_at" DESC 
    User Load (0.6ms) SELECT DISTINCT "users".* FROM "users" INNER JOIN "certifications" ON "certifications"."user_id" = "users"."id" WHERE (certifications.certification_name LIKE '%CCNA%' OR certifications.certification_authority LIKE '%CCNA%') ORDER BY "users"."updated_at" DESC 
    User Load (0.5ms) SELECT DISTINCT "users".* FROM "users" INNER JOIN "qualifications" ON "qualifications"."user_id" = "users"."id" WHERE (qualifications.education LIKE '%CCNA%') ORDER BY "users"."updated_at" DESC 
    User Load (0.5ms) SELECT DISTINCT "users".* FROM "users" INNER JOIN "qualifications" ON "qualifications"."user_id" = "users"."id" WHERE (qualifications.university_major LIKE '%CCNA%') ORDER BY "users"."updated_at" DESC 

에서 검색 할 때 결과입니다.